Search code examples
unit-testingpowershelldscpester

Unit Testing a Class-based DSC resource with Pester


I am having a problem with unit testing a class-based DSC resource. I am trying to Mock a couple of functions in the class and I get a cast error.

PSInvalidCastException: Cannot convert the "bool TestVMExists(string vmPath,     
string vmName)" value of type "System.Management.Automation.PSMethod" to type
"System.Management.Automation.ScriptBlock".

My test code is this:

using module 'C:\Program Files\WindowsPowerShell\Modules\xVMWareVM\xVMWareVM.psm1'

$resource = [xVMWareVM]::new()

   Describe "Set" {

    Context "If the VM does not exist" {

        Mock xVMWareVM $resource.TestVMExists {return $false}
        Mock xVMWareVM $resource.CreateVM

        It "Calls Create VM once" {
            Assert-MockCalled $resource.CreateVM -Times 1
        }
    }
}

Does anyone know how to achieve this?

Thanks in advance


Solution

  • You currently won't be able to mock a class function using Pester. The current workaround is to use Add-Member -MemberType ScriptMethod to replace the function. This means you will not get the mock asserts.

    I borrowed this for DockerDsc tests by @bgelens.

    Without your class code, I haven't been able to test this, but it should give you the idea along with @bgelens code above.

    using module 'C:\Program Files\WindowsPowerShell\Modules\xVMWareVM\xVMWareVM.psm1'
    
       Describe "Set" {
    
        Context "If the VM does not exist" {
            $resource = [xVMWareVM]::new() 
            $global:CreateVmCalled = 0
            $resource = $resource | 
                Add-Member -MemberType ScriptMethod -Name TestVMExists -Value {
                        return $false
                    } -Force -PassThru
            $resource = $resource | 
                Add-Member -MemberType ScriptMethod -Name CreateVM -Value {
                        $global:CreateVmCalled ++ 
                    } -Force -PassThru
    
            It "Calls Create VM once" {
                $global:CreateVmCalled | should be 1
            }
        }
    }