Mock functions in the Pipeline

Hi Guys

I’ve started learning Pester and currently I’m a bit stuck with trying to Mock Functions/Cmdlets in the Pipeline.

For Example when I try to Mock the cmdlets in the below code:

[pre]
$PackageObject = ((Invoke-WebRequest -UseBasicParsing -Method Get -Uri $GetListUrl -Headers @{“Content-Type” = “application/json”; “Authorization” = $apiKey}).Content | ConvertFrom-Json).Value | Where-Object {$_.FileName -like $($packageFileName) } | Select-Object Id,FileName
[/pre]

This is the Mock commands I’m trying to use:

[pre]
Describe "Get-Package" {
It "If Package Downloaded Successfully" {
Mock -CommandName Invoke-WebRequest -MockWith {Return "http://someurlreturn.com"}
Mock -CommandName Test-Path -MockWith {Return $true}
Mock -CommandName ConvertFrom-Json -MockWith {}
Mock -CommandName Where-Object
Mock -CommandName Select-Object {Return "sdfksldfk" }
$apiKey = "blahahah"
$PackageName = "package"
$PackageVersion = "1.1.1.1"
$Test = Get-Package
$Test | Should be "dlfjklsdjfsdklfj"

[/pre]

If I test the Select-Object mock outside of the pipeline its works fine.

Also its seems that the pipeline complicates unit testing. Should be be used when writing functions that will be unit tested?

Hi Gert,

In order to successfully mock commands you have to first understand what you are getting back in a real scenario calling that command. So if your Invoke-Webrequest returns data in Json format, then you have to create that test data and return it as part of your mock. I see that you are retrieving the “content” key from the returned data. Your mock data has to have this content key value present in order for the rest of the commands to work properly.

In your code snippet, I would only mock Invoke-Webrequest and let the rest of the commands do their work from whatever test data you create.

Example:
# code in your module:

$Response = (Invoke-WebRequest -URI www.test.com -Method Get -Headers @{ContentType = json}).Content

# code in your test:

$ResponseTestData = @(
  Content = @{
      SomeData = 'more data'

})

Mock-Command Invoke-WebRequest { $ResponseTestData }

$result = Get-Package
$result.id | Should be <blah>
$result.Filename | Should be <blah>

 

Hope that helps.

-Michael