I've found a lot of questions about mocking a function (method) within a PowerShell class. The question I have (and can't find an answer for) is, is it possible to mock a cmdlet call that is contained within a PowerShell class?
To be clear - this is about testing the function/method in the class, not mocking the function/method from the class for which there are a number of options available.
Example: PowerShell Class - test.psm1
class MyClass {
[string]$filecontent
MyClass() {}
[void] GetFileContent([string]$filepath) {
$this.filecontent = Get-Content -Path $filepath -raw
}
}
Pester file:
using module .\test.psm1
Describe "MyClass" {
BeforeAll {
$objClass = [MyClass]::new()
Mock Get-Content { return "this-is-a-test" }
$objClass.GetFileContent("c:\temp\myfile.txt")
}
It "Should update class variable" {
$objClass.filecontent | Should -be "test-is-a-test"
}
AfterAll {
Remove-Variable objClass
}
}
I had expected (or rather hoped) to mock the cmdlet Get-Content within the class function/method GetFileContent, but Get-Content is not mocked - and it tries to call the file which may not exist in testing. Any ideas of how to mock these cmdlets?
Many thanks
Martin
The key to make this work is to use the -ModuleName
Parameter in your Mock
statement, this is so the cmdlet gets overridden in the Module's scope.
Optional string specifying the name of the module where this command is to be mocked. This should be a module that calls the mocked command; it doesn't necessarily have to be the same module which originally implemented the command.
The argument for ModuleName
in this case would be test
, this is determined by your psm1
file name.
In summary:
using module .\test.psm1
Describe 'MyClass' {
BeforeAll {
Mock Get-Content -ModuleName test { return 'this-is-a-test' }
$objClass = [MyClass]::new()
$objClass.GetFileContent('c:\temp\myfile.txt')
}
....
....
}
Alternatively, hint provided by zett42, you can use InModuleScope
wrapping Describe
:
using module .\test.psm1
InModuleScope 'test' {
Describe 'MyClass' {
BeforeAll {
Mock Get-Content { return 'this-is-a-test' }
$objClass = [MyClass]::new()
$objClass.GetFileContent('c:\temp\myfile.txt')
}
....
....
}
}