liveBook · Manning

Unit test

As explained in Practical Automation with PowerShell: Effective scripting from the console to the cloud

A unit test is a software test that verifies the behavior of a small, isolated unit of code.

A unit test verifies the logic of one small unit of code—typically a single PowerShell function. It should be self-contained: test the function’s decisions, inputs, outputs, and error handling without depending on the current machine, network, or another external system. section 13.2 section 13.3.4

Functions make automation easier to test because PowerShell loads them into memory, letting you invoke the function repeatedly without running unrelated script actions. Early checks can call a loaded function directly with representative parameters, including strings that PowerShell converts to declared DateTime parameters; these calls still perform their real actions unless dependencies are mocked. section 2.1.3

Use Pester to make tests repeatable. A test file groups checks with Describe and optionally Context; each It block contains an independent test, and Should confirms the expected result. Variables and setup are not shared automatically between It blocks, so use BeforeAll for one-time setup or BeforeEach for setup that must run before every test. section 13.1

Build a reliable unit test by separating the function’s logic from its outside calls:

  • Write the function first, including explicit handling for expected failures and rethrowing unexpected errors. section 13.2
  • Choose controlled responses for each case the function must handle, rather than relying on a machine’s installed patches or a live website. section 13.2 section 13.3.2
  • Mock commands such as Get-HotFix, Invoke-WebRequest, or ConvertFrom-Html so the test supplies those responses consistently. section 13.2 section 13.3.4
  • Assert both broad outcomes and specific parsed values when the function’s logic requires them, such as returned records, properties, product names, architectures, or absence of supersedence. section 13.3.4

Testing patch-status logic

A patch-status function calls Get-HotFix with a KB identifier and computer name, returns true when the patch is found, returns false for the known “not found” error, and throws other errors. Its unit tests mock Get-HotFix to exercise each result without requiring any particular patch to exist on the test machine. section 13.2

Listing 13.8 Find-KbSupersedence.Unit.Tests.ps1 in-depth with mocks
BeforeAll {
    Set-Location -Path $PSScriptRoot
    . ".\Find-KbSupersedence.ps1"
}
 
Describe 'Find-KbSupersedence' {
    BeforeAll {
        Mock ConvertFrom-Html -ParameterFilter{                  #1
            $URI } -MockWith {
            $File = "$($URI.AbsoluteUri.Split('=')[-1]).html"
            $Path = Join-Path $PSScriptRoot $File
            ConvertFrom-Html -Path $Path
        }
 
        Mock Invoke-WebRequest -MockWith {
            $File = "$($URI.AbsoluteUri.Split('=')[-1]).html"
            $Path = Join-Path $PSScriptRoot $File
            $Content = Get-Content -Path $Path -Raw
            [pscustomobject]@{
                Content = $Content
            }
        }
    }
 
    It "KB Article is found" {                                   #2
        $KBSearch = Find-KbSupersedence -KbArticle 'KB4521858'
        $KBSearch | Should -Not -Be $null
        $KBSearch | Should -HaveCount 3
 
        $cmd = 'ConvertFrom-Html'                                #3
        Should -Invoke -CommandName $cmd -Times 1
        $cmd = 'Invoke-WebRequest'
        Should -Invoke -CommandName $cmd -Times 3
    }
 
    It "In Depth Search results" {
        $KBSearch = Find-KbSupersedence -KbArticle 'KB4521858'
        $KBSearch.Id |
            Should -Contain '250bfd45-b92c-49af-b604-dbdfd15061e6'
        $KBSearch |
            Where-Object{ $_.Products -contains 'Windows 10' } |
            Should -HaveCount 2
        $KBSearch |
            Where-Object{ $_.Architecture -eq 'AMD64' }  |
            Should -HaveCount 2
        $KB = $KBSearch |
            Where-Object{ $_.Id -eq '83d7bc64-ff39-4073-9d77-02102226aff6' }
        $KB.Products  | Should -Be 'Windows Server 2016'
        ($KB.SupersededBy | Measure-Object).Count | Should -Be 9
    }
 
    It "SupersededBy results" {                                  #4
        $KBMock = Find-KbSupersedence -KbArticle 'KB5008295'
 
        $KBMock.SupersededBy |                                   #5
            Should -Be @($null, $null)
 
        $cmd = 'ConvertFrom-Html'                                #6
        Should -Invoke -CommandName $cmd -Times 1
        $cmd = 'Invoke-WebRequest'
        Should -Invoke -CommandName $cmd -Times 2
    }
}

This Pester test loads a function, replaces web and HTML commands with local fixture data in BeforeAll, then checks deterministic results inside an It block. section 13.3.4

Keep integration tests separate. A unit test can require an exact GUID or parsed architecture because its inputs are mocked; an integration test may query the live source but should make broader assertions that tolerate third-party changes. Before changing existing automation, add unit tests to preserve current behavior, and run unit and integration tests automatically for pull requests. section 13.3.4 section 14.4

How Practical Automation with PowerShell: Effective scripting from the console to the cloud covers it

How deep it goes
Explains Pester structure, setup scope, mocks, assertions, and the unit-versus-integration boundary through complete scenarios.
Examples
Demonstrates patch-status checks and KB supersedence parsing with mocked cmdlets, web responses, HTML fixtures, GUIDs, products, and architectures.
What it assumes
Assumes ability to write and invoke PowerShell functions while introducing Pester test organization and mock-based isolation.
What you can do after
Apply it via Pester to isolate PowerShell functions, control dependencies with mocks, and validate expected results.
How it connects
Connects functions, Pester, mocks, integration tests, error handling, web scraping, and pull requests.

Also explained in

Compare how 9 books explain unit test →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Practical Automation with PowerShell: Effective scripting from the console to the cloud. The section links point to the parts of the book it draws on.