Short description:
I'm trying use Pester to mock the contents of a file and then iterate through each line and each character of that fake data, but I'm getting this error: "the array index evaluated to null." when trying to access the characters of a line.
Background:
I have a Powershell function that reads the contents of the global.asax.cs file.
Example of the file I'm reading from:
namespace MockData
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
MvcHandler.DisableMvcResponseHeader = true;
}
}
}
Then, my function will use Get-Content to read the file and iterate through each line and each character. Example (simplified version, the $index variable looks nasty in this example but it's needed in the real code):
$contents = Get-Content $filePath
$index = 0
$bracketCounter = 0
Do {
foreach($char in $contents[$index].ToCharArray()) {
if($char -eq "{") {
$bracketCounter++
}
elseif ($char -eq "}") {
$bracketCounter--
}
}
$index++
} While ($bracketCounter -gt 0)
Now in Pester, this is the code for my test:
It "check for success" {
Mock Get-Content {
$content = "namespace MockData
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
MvcHandler.DisableMvcResponseHeader = true;
}
}
}"
return $content
} -ParameterFilter { $Path -like "*asax*"}
[string[]]$errors = MyPowershellFile
$errors | should BeNullOrEmpty
}
Expected results:
My expected results is that the Pester test iterates through the mock contents the same way it does with the real contents.
The error from Pester happens when calling this line:
foreach($char in $contents[$index].ToCharArray())
I get "RuntimeException: Index operation failed; the array index evaluated to null."
I think this happens because in the real function, the first element of $contents is the first line of the file.
$contents[0] = namespace MockData
While in the Pester function, the first element of $contents is the first character.
$contents[0] = n
Is there a good way to work around this? I'm running out of ideas.
Thanks in advance for anyone reading this question.
Why not write to the TestDrive and then mock:
Describe 'test things' {
#create a here-string and write the contents to the testdrive
@"
namespace MockData
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
MvcHandler.DisableMvcResponseHeader = true;
}
}
}
"@ | Set-Content -Path TestDrive:\testfile.txt
#Set up the mock to get-content
Mock Get-Content {
Get-Content TestDrive:\testfile.txt
} -ParameterFilter {$path -like "*asax*"}
#make sure the content matches
it "finds strings in mocked content" {
Get-Content abc.asax | Select-String MVCHandler | Should -Match 'MvcHandler.DisableMvcResponseHeader = true;'
}
#make sure the line count is correct
it 'should have 10 lines of content' {
(Get-Content def.asax).Count | Should -BeExactly 10
}
#make sure our mock was called the correct number of times
it "called mocked get-content twice" {
Assert-MockCalled Get-Content -Times 2
}
}
This will create an actual file that mimics production so that you can test it correctly.