Learn To Use Verbose Output Streams In Your Pester Tests

I’m going to file this under “Either I’m a genius, or there’s a much better way and everyone knows it except for me.”

I recently began adding a suite of Pester tests to one of my projects and I found myself needing to mock some unit tests against a particular function that would modify a variable based on the parameter specified. Since all the functions I write nowadays are considered advanced functions (and yours should be too, they’re free!), I discovered a nice way to test the function’s actions using the -Verbose stream output.

Full source code for these examples is available on the Pester branch of my KaceSMA project on GitHub

A Real World Example

I’m going to use a public function Get-SmaAsset for this example. For this particular function, I’m wrapping an API call and passing a specific endpoint as a string, determined by the parameter set(s) given. Here is the relevant bit of code:

We see $Endpoint being dynamically defined according to the parameters fed to the parent Get-SmaAsset function. I needed to ensure that the correct value of $Endpoint was being fed to the next part of the chain, which was the Invoke-RestMethod call to the API itself. The last thing I want to debug is why my API call is hitting the wrong endpoint. (Not to mention the potentially disastrous results when HTTP methods other than GET are used!)

You don’t need an intimate knowledge of the project to understand what’s going on here – I’m really just wanting to make sure that this particular function only uses a single GET method, and that it calls the correct endpoint. An easy way to do this is by leveraging the verbose output stream to ensure that Get-SmaAsset is in fact, seeking out the correct endpoint with the correct HTTP method.

Here’s part of what the function returns when run verbosely under normal circumstances:

Plugging It Into Pester

Pester is the perfect tool to test that my API calls go out consistently every time, and to do so I just need to use the Verbose output stream, then mock some response data, and then I should get a pretty clear idea exactly what is going on within my function scope.

Let’s see what the ‘Backend Calls’ context block looks like for this particular test:

Now, let’s focus on a single test. This is where the ‘cool’ factor of output streams comes into play. $Generic performs a mocked call to our function, which has a curious bit at the end, 4>&1.

What this does is take the verbose output stream ( 4) and redirect it to stdout ( >&1) for our test to report on. The beauty of this is in it’s simplicity. We don’t have to modify anything in our code itself since it’s an advanced function, and -Verbose is included by default.

When we do this we get several key benefits. By explicitly stating the known-good verbose output in our tests, it would begin failing if any of these scenarios occurred in our codebase:

  • If the endpoint is changed intentionally
  • If the endpoint selection logic is flawed
  • If the HTTP method declared is changed
  • If the HTTP Method is ever used more than once

I hope this has been helpful in exploring how the verbose output stream can help detect stealthy bugs in your codebase.

5 thoughts on “Learn To Use Verbose Output Streams In Your Pester Tests

  1. Nathaniel Webb (ArtisanByteCrafter) Post author

    As an added bonus, statically assigning our data models in this way allows us to discover if and how an upstream API data model has changed. If a provider modified their API response, our test would reflect that inconsistency in either returned objects or number of NoteProperty objects in the return.

  2. Richard Fresow

    Can not find Get-SmaAsset in your code (only in comment help). Did you rename it to Get-Asset?

    1. Nathaniel Webb (ArtisanByteCrafter) Post author

      Thanks for stopping by! I would encourage you to not view unit tests as “How do i tell if my code will work” but rather design your tests first with how you want your code to work, then write the code to pass those tests. It’s an idea called Test-Driven Development. Check it out!

Comments are closed.