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

Tagged: 

This topic contains 3 replies, has 3 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 2 years, 1 month ago.

  • Author
    Posts
  • #20474
    Profile photo of Stephen Yeadon
    Stephen Yeadon
    Participant

    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
      }
    }
    
  • #20475
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

  • #20476
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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'
            }
        }
    }
    
  • #20477
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

You must be logged in to reply to this topic.