I am working on a module that wraps the API of one of our partners. As such, most functions just pass values to Invoke-RestMethod and return the response.
I am experiencing a strange issue where the private function that actually calls Invoke-RestMethod is returning a CommandNotFoundException but only when attempting to pass multiple objects in via the pipeline and only when I try to run the entire module’s test suite.
Here is an example of a working test:
Context 'Pipelining a single object' {
BeforeAll {
Mock -CommandName $internalApiFunction { ($Body | ConvertFrom-Json) } -ModuleName $moduleName
[PSCustomObject]$testInput = [PSCustomObject]@{
Type = 'A'
Name = 'foo.doma.in'
}
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSUserDeclaredVarsMoreThanAssignments',
'',
Justification = 'Variable is used in a different scope'
)]
$result = $testInput | Add-RecordViaApi
}
It 'Passes the correct "<DataType>" to the API' -TestCases @(
@{DataType = 'Type'}
@{DataType = 'Name'}
) {
$expected = $testInput.$DataType
$result.records[0].$DataType | Should -BeExactly $expected
}
}
Immediately below that Context block (in the same test script) is this one:
Context 'Pipelining multiple objects' {
BeforeAll {
Mock -CommandName $internalApiFunction { ($Body | ConvertFrom-Json) } -ModuleName $moduleName
[PSCustomObject]$testInput = @(
[PSCustomObject]@{ Type = 'A'; Name = 'foo.doma.in' }
[PSCustomObject]@{ Type = 'A'; Name = 'bar.doma.in' }
)
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSUserDeclaredVarsMoreThanAssignments',
'',
Justification = 'Variable is used in a different scope'
)]
$result = $testInput | Add-RecordViaApi
}
It 'Invokes the API only once' {
Should -Invoke -CommandName $internalApiFunction -Times 1 -Exactly
}
}
As far as I can tell, the only difference between the 2 tests is the number of objects being passed into the pipeline. The first test always passes but the latter fails when run as part of the full test suite:
[-] Add-RecordViaApi.Pipelining multiple objects.Invokes the API only once 450ms (447ms|3ms)
CommandNotFoundException: Could not find Command Invoke-ApiAsync
Function Invoke-ApiAsync
does exist; if it did not then the first test would also fail because Add-RecordViaApi explicitly depends on it.
This is how I usually invoke Pester during my workflow:
powershell.exe -NonInteractive -Command 'Invoke-Pester; gci -Recurse -File | Invoke-ScriptAnalyzer'; Get-Date
When I invoke Pester as above, the multi-object pipeline test fails. When I invoke just that one test script, the test passes:
powershell.exe -NonInteractive -Noprofile -Command 'Invoke-Pester -Path "./Tests/Add-RecordViaApi.Tests.ps1"'; Get-Date