Pester How do I mock up an object to be used as a paramater

How do I mock up an object so that I can pass it to the method that I want to test. The mocked object needs to have methods of its own that I would want to mock the output of. A simple example can be found below.

Function Method-ToTest ($obj, $value)
{
  $obj.Method($value)
}

Describe “Method-ToTest” {
  Mock $obj = 
  It “Calls tMethod to test” {
     Method-ToTest $obj | Should Be $true
  }
}

You create new objects by using New-Object. You’d create an object of the type Object or PSObject, and then add members - including properties and methods. This isn’t necessarily a quick-and-easy process, as PowerShell isn’t presently designed with this use case in mind. What you probably really want is full class support, which we don’t yet have.

There’s no functionality for creating mock objects built into Pester; it only helps you with mocking PowerShell commands. The typical use case is you’ve got a PowerShell cmdlet or function which returns an object, and then your code under test does something with that object:

function Get-Thingy
{
    $object =  New-Object psobject -Property @{
        ThingyProperty = 'ThingyValue'
    }

    Add-Member -InputObject $object -MemberType ScriptMethod -Name UpperCaseThingy -Value {
        return $this.ThingyProperty.ToUpper()
    }

    return $object
}

function FunctionUnderTest
{
    $thingy = Get-Thingy
    return $thingy.UpperCaseThingy()
}

In practice, Get-Thingy would probably be returning some sort of .NET object, but here I’m just building up a simple custom object with one property and one method. This happens to be exactly how you would construct your mock of Get-Thingy:

Describe 'FunctionUnderTest' {
    Context 'Without Mocking' {
        It 'Returns the default value' {
            FunctionUnderTest | Should Be 'THINGYVALUE'
        }
    }

    Context 'With Mocking' {
        Mock Get-Thingy {
            $object =  New-Object psobject -Property @{
                ThingyProperty = 'MockedValue'
            }

            Add-Member -InputObject $object -MemberType ScriptMethod -Name UpperCaseThingy -Value {
                return $this.ThingyProperty.ToUpper()
            }

            return $object
        }

        It 'Returns the mocked object' {
            FunctionUnderTest | Should Be 'MOCKEDVALUE'
        }
    }
}

If your code under test happens to accept the object as a parameter already (such as with your Method-ToTest example), then you don’t even need to use Pester’s Mock command; just build up the object out in your test script, and pass it in.