Problem
When a Hashtable
is used as input for Should
, Pester outputs only the typename instead of the content:
Describe 'test' {
It 'test case' {
$ht = @{ foo = 21; bar = 42 }
$ht | Should -BeNullOrEmpty
}
}
Output:
Expected $null or empty, but got @(System.Collections.Hashtable).
Expected output like:
Expected $null or empty, but got @{ foo = 21; bar = 42 }.
Cause
Looking at Pester source, the test input is formatted by private function Format-Nicely
, which just casts to String
if the value type is Hashtable
. This boils down to calling Hashtable::ToString()
, which just outputs the typename.
Workaround
As a workaround I'm currently deriving a class from Hashtable
that overrides the ToString
method. Before passing the input to Should
, I cast it to this custom class. This makes Pester call my overridden ToString
method when formatting the test result.
BeforeAll {
class MyHashTable : Hashtable {
MyHashTable( $obj ) : base( $obj ) {}
[string] ToString() { return $this | ConvertTo-Json }
}
}
Describe 'test' {
It 'test case' {
$ht = @{ foo = 21; bar = 42 }
[MyHashTable] $ht | Should -BeNullOrEmpty
}
}
Now Pester outputs the Hashtable
content in JSON format, which is good enough for me.
Question
Is there a more elegant way to customize Pester output of Hashtable
, which doesn't require me to change the code of each test case?
Update-TypeData
to create a type-level.ToString()
override, but it turns out that only works with explicit.ToString()
calls, and not with casts and string interpolation, which smells like a bug (as of v7.1) - see GitHub issue #14561 – Bordeaux