2

What makes Assert-VerifiableMocks different from Assert-MockCalled in Pester? I've been reading

but still wonder: are the following sections of code equivalent and interchangeable?

Using Assert-MockCalled:

Mock Invoke-MongoCommmand {}
Set-TargetResource -UserName $test_username -Ensure "Absent"
Assert-MockCalled Invoke-MongoCommand -ParameterFilter {
    $Expression -eq "db.dropUser('$test_username')"
}

Using Assert-VerifiableMocks:

Mock Invoke-MongoCommand {} -Verifiable -ParameterFilter {
    $Expression -eq "db.dropUser('$test_username')"
}
Set-TargetResource -UserName $test_username -Ensure "Absent"
Assert-VerifiableMocks
QIU Quan
  • 23
  • 3

2 Answers2

2

The functionality of Assert-VerifiableMocks isn't a subset of Assert-MockCalled it's a disjoint set. With Assert-VerifiableMocks you can verify many mocks are called at the same time, but as already mentioned you cannot verify any mocks are not called. I have an example below to more fully explain these two differences testing an example 'Get-ValueSum'.

If you notice with Assert-verifiableMocks you can verify that the test has called all the expected mocks in a single assert.

Assert-Verifiable Sample

describe 'Assert-MockCalled vs Assert-VerifiableMocks in Pester' {
    function Get-Value1{ 1}
    function Get-Value2{ 2}
    function Get-Value3{ 3}
    
    # Should never be called by Get-ValueSum
    function Get-Value4{ 4}

    # Sums Value 1, 2 & 3, but 4 only if $include4 is specified
    function Get-ValueSum
    {
        param([switch] $inclued4 )
        if($inclued4)
        {
            return (Get-Value1) + (Get-Value2) + (Get-Value3) + (Get-Value4)
        }
        else
        {
            return (Get-Value1) + (Get-Value2) + (Get-Value3)
        }
    }

    context 'assert verifiable' {
        # Mark the first 3 mocks as verifiable 
        # because they should not be called 
        mock -CommandName Get-Value1 -MockWith { 2} -Verifiable
        mock -CommandName Get-Value2 -MockWith { 3} -Verifiable
        mock -CommandName Get-Value3 -MockWith { 4} -Verifiable
        # Add this so we can verify it is not called
        mock -CommandName Get-Value4 -MockWith { 99} 
        
        $result = Get-ValueSum

        it 'Should call the 3 expected value calls' {
            Assert-VerifiableMock
        }

        it 'should not call get-value 4' {
            Assert-MockCalled -CommandName Get-Value4 -Times 0
        }

        it 'should have gotten a sum of 9' {
            $result | should be 9
        }
        # add test for #$include4
    }
}

Assert-MockCalled Sample

describe 'Assert-MockCalled vs Assert-VerifiableMocks in Pester' {
    function Get-Value1{ 1}
    function Get-Value2{ 2}
    function Get-Value3{ 3}
    
    # Should never be called by Get-ValueSum
    function Get-Value4{ 4}

    # Sums Value 1, 2 & 3, but 4 only if $include4 is specified
    function Get-ValueSum
    {
        param([switch] $inclued4 )
        if($inclued4)
        {
            return (Get-Value1) + (Get-Value2) + (Get-Value3) + (Get-Value4)
        }
        else
        {
            return (Get-Value1) + (Get-Value2) + (Get-Value3)
        }
    }

    context 'assert mock called method' {
        # Add all mocks so we can verify 
        # if they were called or not individually
        mock -CommandName Get-Value1 -MockWith { 3} 
        mock -CommandName Get-Value2 -MockWith { 4} 
        mock -CommandName Get-Value3 -MockWith { 5} 
        mock -CommandName Get-Value4 -MockWith { 99} 

        $result = Get-ValueSum

        it 'Should call the 3 expected value calls' {
            Assert-MockCalled -CommandName Get-Value1 -Times 1
            Assert-MockCalled -CommandName Get-Value2 -Times 1
            Assert-MockCalled -CommandName Get-Value3 -Times 1
        }

        it 'should not call get-value 4' {
            Assert-MockCalled -CommandName Get-Value4 -Times 0
        }

        it 'should have gotten a sum of 12' {
            $result | should be 12
        }
        # add test for #$include4
    }
}
TravisEz13
  • 2,263
  • 1
  • 20
  • 28
  • Several bugs in your sample code which can confuse people. For example, if($inclued4) { return (Get-Value1) + (Get-Value2) + (Get-Value3) + (Get-Value4) # Don't forget adding Get-Value4 } – Cary Jul 23 '20 at 07:12
  • I addressed the bug mentioned. – TravisEz13 Aug 14 '20 at 19:39
0

In your sample they are the same, however it is about how and what you want to check. For example, you want to check if something is not called. You would probably use:

Assert-MockCalled xxx -Times 0 -ParameterFilter {$x -eq "foo"}

This would be impossible with Assert-VerifiableMocks

Peter
  • 27,590
  • 8
  • 64
  • 84
  • Agree. I try to verify functions never get called in exactly the same way. This makes me believe that Assert-VerifiableMocks just provides a subset of Assert-MockCalled's functionality. – QIU Quan May 07 '16 at 15:45