Skip to content

Commit

Permalink
mocking complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
mwrock committed Oct 22, 2012
1 parent 6ebdd20 commit 4178c34
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 16 deletions.
1 change: 1 addition & 0 deletions Functions/Describe.ps1
Expand Up @@ -18,4 +18,5 @@ function Describe($name, [ScriptBlock] $fixture) {
Cleanup Cleanup
$results.Describes += $results.CurrentDescribe $results.Describes += $results.CurrentDescribe
$results.TestDepth -= 1 $results.TestDepth -= 1
Clear-Mocks
} }
80 changes: 73 additions & 7 deletions Functions/Mock.Tests.ps1
Expand Up @@ -19,7 +19,6 @@ Describe "When calling Mock on existing function" {
It "Should Invoke the mocked script" { It "Should Invoke the mocked script" {
$result.should.be("I am the mock test that was passed yoyo") $result.should.be("I am the mock test that was passed yoyo")
} }
Clear-Mocks
} }


Describe "When calling Mock on existing cmdlet" { Describe "When calling Mock on existing cmdlet" {
Expand All @@ -30,7 +29,6 @@ Describe "When calling Mock on existing cmdlet" {
It "Should Invoke the mocked script" { It "Should Invoke the mocked script" {
$result.should.be("I am not Get-Process") $result.should.be("I am not Get-Process")
} }
Clear-Mocks
} }


Describe "When calling Mock on non-existing function" { Describe "When calling Mock on non-existing function" {
Expand All @@ -43,7 +41,6 @@ Describe "When calling Mock on non-existing function" {
It "Should throw correct error" { It "Should throw correct error" {
$result.Exception.Message.should.be("Could not find command NotFunctionUnderTest") $result.Exception.Message.should.be("Could not find command NotFunctionUnderTest")
} }
Clear-Mocks
} }


Describe "When calling Mock on existing function without matching params" { Describe "When calling Mock on existing function without matching params" {
Expand All @@ -54,7 +51,6 @@ Describe "When calling Mock on existing function without matching params" {
It "Should redirect to real function" { It "Should redirect to real function" {
$result.should.be("I am a real world test") $result.should.be("I am a real world test")
} }
Clear-Mocks
} }


Describe "When calling Mock on existing function with matching params" { Describe "When calling Mock on existing function with matching params" {
Expand All @@ -65,7 +61,6 @@ Describe "When calling Mock on existing function with matching params" {
It "Should return mocked result" { It "Should return mocked result" {
$result.should.be("fake results") $result.should.be("fake results")
} }
Clear-Mocks
} }


Describe "When calling Mock on cmdlet Used by Mock" { Describe "When calling Mock on cmdlet Used by Mock" {
Expand All @@ -76,7 +71,6 @@ Describe "When calling Mock on cmdlet Used by Mock" {
It "Should Invoke the mocked script" { It "Should Invoke the mocked script" {
$result.should.be("I am not Invoke-Command") $result.should.be("I am not Invoke-Command")
} }
Clear-Mocks
} }


Describe "When calling Mock on More than one command" { Describe "When calling Mock on More than one command" {
Expand All @@ -92,5 +86,77 @@ Describe "When calling Mock on More than one command" {
It "Should Invoke the mocked script for the second Mock" { It "Should Invoke the mocked script for the second Mock" {
$result2.should.be("I am the mock test") $result2.should.be("I am the mock test")
} }
Clear-Mocks }

Describe "When Applying multiple Mocks on a single command" {
Mock FunctionUnderTest {return "I am the first mock test"} -parameterFilter {$param1 -eq "one"}
Mock FunctionUnderTest {return "I am the Second mock test"} -parameterFilter {$param1 -eq "two"}

$result = FunctionUnderTest "one"
$result2= FunctionUnderTest "two"

It "Should Invoke the mocked script for the first Mock" {
$result.should.be("I am the first mock test")
}
It "Should Invoke the mocked script for the second Mock" {
$result2.should.be("I am the Second mock test")
}
}

Describe "When Applying multiple Mocks with filters on a single command where both qualify" {
Mock FunctionUnderTest {return "I am the first mock test"} -parameterFilter {$param1.Length -gt 0 }
Mock FunctionUnderTest {return "I am the Second mock test"} -parameterFilter {$param1 -gt 1 }

$result = FunctionUnderTest "one"

It "The last Mock should win" {
$result.should.be("I am the Second mock test")
}
}

Describe "When Applying multiple Mocks on a single command where one has no filter" {
Mock FunctionUnderTest {return "I am the first mock test"} -parameterFilter {$param1 -eq "one"}
Mock FunctionUnderTest {return "I am the paramless mock test"}
Mock FunctionUnderTest {return "I am the Second mock test"} -parameterFilter {$param1 -eq "two"}

$result = FunctionUnderTest "one"
$result2= FunctionUnderTest "three"

It "The parameterless mock is evaluated last" {
$result.should.be("I am the first mock test")
}

It "The parameterless mock will be applied if no other wins" {
$result2.should.be("I am the paramless mock test")
}
}

Describe "When Creaing a Verifiable Mock that is not called" {
Mock FunctionUnderTest {return "I am a verifiable test"} -Verifiable -parameterFilter {$param1 -eq "one"}
FunctionUnderTest "three"

try {
Assert-VerifiableMocks
} Catch {
$result=$_
}

It "Should throw" {
$result.Exception.Message.should.be("`r`n Expected FunctionUnderTest to be called with `$param1 -eq `"one`"")
}
}

Describe "When Creaing a Verifiable Mock that is called" {
Mock FunctionUnderTest {return "I am a verifiable test"} -Verifiable -parameterFilter {$param1 -eq "one"}
FunctionUnderTest "one"

try {
Assert-VerifiableMocks
} Catch {
$result=$_
}

It "Should not throw" {
$result -eq $null
}
} }
25 changes: 16 additions & 9 deletions Functions/Mock.ps1
Expand Up @@ -2,10 +2,9 @@ $mockTable = @{}


function Mock ([string]$commandName, [ScriptBlock]$mockWith, [switch]$verifiable, [ScriptBlock]$parameterFilter = {$True}) function Mock ([string]$commandName, [ScriptBlock]$mockWith, [switch]$verifiable, [ScriptBlock]$parameterFilter = {$True})
{ {
# If verifiable, add to a verifiable hashtable
$origCommand = (Get-Command $commandName -ErrorAction SilentlyContinue) $origCommand = (Get-Command $commandName -ErrorAction SilentlyContinue)
if(!$origCommand){ Throw "Could not find Command $commandName"} if(!$origCommand){ Throw "Could not find Command $commandName"}
$blocks = @{Mock=$mockWith; Filter=$parameterFilter} $blocks = @{Mock=$mockWith; Filter=$parameterFilter; Verifiable=$verifiable}
$mock = $mockTable.$commandName $mock = $mockTable.$commandName
if(!$mock) { if(!$mock) {
if($origCommand.CommandType -eq "Function") { if($origCommand.CommandType -eq "Function") {
Expand All @@ -17,19 +16,26 @@ function Mock ([string]$commandName, [ScriptBlock]$mockWith, [switch]$verifiable
$newContent=Get-Content function:\MockPrototype $newContent=Get-Content function:\MockPrototype
Set-Item Function:\script:$commandName -value "$cmdLetBinding `r`n param ( $params ) `r`n$newContent" Set-Item Function:\script:$commandName -value "$cmdLetBinding `r`n param ( $params ) `r`n$newContent"
$mock=@{OriginalCommand=$origCommand;blocks=@($blocks)} $mock=@{OriginalCommand=$origCommand;blocks=@($blocks)}
} else {$mock.blocks += $blocks} } else {
if($blocks.Filter.ToString() -eq "`$True") {$mock.blocks = ,$blocks + $mock.blocks} else { $mock.blocks += $blocks }
}
$mockTable.$commandName = $mock $mockTable.$commandName = $mock
# param filters are met, mark in the verifiable table
} }


function Assert-VerifiableMocks { function Assert-VerifiableMocks {
# Check that the Verifiables have all been called $unVerified=@{}
# if not, throw $mockTable.Keys | % {
$m=$_; $mockTable[$m].blocks | ? { $_.Verifiable } | % { $unVerified[$m]=$_ }
}
if($unVerified.Count -gt 0) {
foreach($mock in $unVerified.Keys){
$message += "`r`n Expected $mock to be called with $($unVerified[$mock].Filter)"
}
throw $message
}
} }


function Clear-Mocks { function Clear-Mocks {
# Called at the end of Describe
# Clears the Verifiable table
$mockTable.Keys | % { Microsoft.PowerShell.Management\Remove-Item function:\$_ } $mockTable.Keys | % { Microsoft.PowerShell.Management\Remove-Item function:\$_ }
$script:mockTable = @{} $script:mockTable = @{}
Microsoft.PowerShell.Management\Get-ChildItem Function: | ? { $_.Name.StartsWith("PesterIsMocking_") } | % {Microsoft.PowerShell.Management\Rename-Item Function:\$_ "script:$($_.Name.Replace('PesterIsMocking_', ''))"} Microsoft.PowerShell.Management\Get-ChildItem Function: | ? { $_.Name.StartsWith("PesterIsMocking_") } | % {Microsoft.PowerShell.Management\Rename-Item Function:\$_ "script:$($_.Name.Replace('PesterIsMocking_', ''))"}
Expand All @@ -41,7 +47,8 @@ function MockPrototype {
$idx=$mock.blocks.Length $idx=$mock.blocks.Length
while(--$idx -ge 0) { while(--$idx -ge 0) {
if(&($mock.blocks[$idx].Filter)) { if(&($mock.blocks[$idx].Filter)) {
&($mockTable.$functionName.blocks.mock) @PSBoundParameters $mock.blocks[$idx].Verifiable=$false
&($mockTable.$functionName.blocks[$idx].mock) @PSBoundParameters
return return
} }
} }
Expand Down

0 comments on commit 4178c34

Please sign in to comment.