1

I have a function that I would like to include in my unit tests but I'm unable to figure out how. The method takes in an ErrorRecord object (from an Invoke-RestMethod call), grabs the status code and generates a custom error message. Here is what the first portion of the call looks like:

function Resolve-RestError {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        $RequestError
    )
    $statusCode = $requestError.Exception.Response.StatusCode.value__
    switch ($statusCode) {

The problem that I am running into is in the recreation of the ErrorRecord object. I have spent many hours looking for a way to recreate the error object, but I am not able to recreate it exactly.

In the actual ErrorRecord object during execution, accessing the Response.StatusCode field returns a string with a description of the code. To access the actual value you need to call Response.StatusCode.value__. It seems that it's not possible to reconstruct an internal .value__ variable as this is done by the JIT compiler (from my understanding). Is there a way to either add a .value__ property to a custom object, or simply mock that variable during my tests?

Efie
  • 1,430
  • 2
  • 14
  • 34

1 Answers1

1

You're right it doesn't seem overly simple to recreate an ErrorRecord object. My goto for this sort of thing is to simulate the output I want to Mock in my test and then store that result via Export-CliXml but when trying this with an ErrorRecord you only get as far as Exception.Response and the rest is lost in the conversion (even when setting a -Depth value).

There might be a smarter way, but one workaround would be to just fake the object as follows (note you didn't provide your full Function so I just created a simplified version of it to prove it worked for this specific case):

function Resolve-RestError {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        $RequestError
    )
    $statusCode = $RequestError.Exception.Response.StatusCode.value__

    Return $statusCode
}

Describe 'Resolve-RestError' {

    It 'Should handle a 404' {

        $ErrorRecord = [pscustomobject]@{ 
            Exception = @{
                Response = @{
                    StatusCode = @{
                        value__ = 404
                    }
                }
            }
        }
        
        Resolve-RestError -RequestError $ErrorRecord | Should -Be 404
    }
}
Mark Wragg
  • 22,105
  • 7
  • 39
  • 68
  • Interesting idea, for value__ = 404, is that basically just implicitly assigning an enum value as a property of status code? – Efie Jun 25 '20 at 15:24
  • 1
    Yeah I think strictly speaking it will just appear as an integer property. This isn’t creating an equivalent object but it’s maybe scaffolding it enough to get your function to fire properly. – Mark Wragg Jun 25 '20 at 15:26