Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions docs/commands/Should-HaveParameter.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,49 @@ This assertion inspects command metadata and can also verify parameter details s
### EXAMPLE 1

```powershell
Get-Command "Invoke-WebRequest" | Should -HaveParameter Uri -Mandatory
Get-Command Invoke-WebRequest | Should-HaveParameter Uri -Type ([uri]) -Mandatory
```

This test passes, because it expected the parameter URI to exist and to
be mandatory.
This assertion passes, because `Invoke-WebRequest` has a mandatory `-Uri` parameter of type `[uri]`.

### EXAMPLE 2

```powershell
function Get-Cat {
[CmdletBinding(DefaultParameterSetName = 'ByName')]
param(
[Parameter(ParameterSetName = 'ByName', Mandatory)]
[Alias('Id')]
[string] $Name,
[Parameter(ParameterSetName = 'ByIndex', Mandatory)]
[int] $Index,
[ValidateSet('Json', 'Xml')]
[string] $Format = 'Json'
)
}
Describe 'Get-Cat public contract' {
It 'requires a Name' {
Get-Command Get-Cat | Should-HaveParameter Name -Type ([string]) -Mandatory -Alias 'Id'
}
It 'defaults Format to Json' {
Get-Command Get-Cat | Should-HaveParameter Format -Type ([string]) -DefaultValue 'Json'
}
}
```

A typical real-life use is locking down the public API of your own command. These assertions pass, because `-Name` is a mandatory `[string]` with the alias `Id`, and `-Format` is an optional `[string]` that defaults to `Json`.

### EXAMPLE 3

```powershell
Get-Command Get-Cat | Should-HaveParameter Index -InParameterSet 'ByIndex'
```

This assertion passes, because the `-Index` parameter (from the `Get-Cat` function above) belongs to the `ByIndex` parameter set.

## PARAMETERS

Expand Down
92 changes: 43 additions & 49 deletions docs/commands/Should-Invoke.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,100 +55,94 @@ passed to Should-Invoke, Should-Invoke will throw an exception.
### EXAMPLE 1

```powershell
Mock Set-Content {}
function Save-Report ($Path, $Content) {
Set-Content -Path $Path -Value $Content
}

Describe 'Save-Report' {
It 'writes the report to disk' {
Mock Set-Content

{...
Some Code ...}
Save-Report -Path 'report.txt' -Content 'All systems green'

Should-Invoke Set-Content
Should-Invoke Set-Content -Times 1 -Exactly
}
}
```

This will throw an exception and cause the test to fail if Set-Content is not called in Some Code.
Asserts that `Save-Report` wrote to disk by calling the mocked `Set-Content` exactly once. The test fails if `Set-Content` was not called, or was called more than once.

### EXAMPLE 2

```powershell
Mock Set-Content -parameterFilter {$path.StartsWith("$env:temp\")}
Mock Set-Content

{...
Some Code ...}
Save-Report -Path 'report.txt' -Content 'All systems green'

Should-Invoke Set-Content 2 { $path -eq "$env:temp\test.txt" }
Should-Invoke Set-Content -ParameterFilter { $Path -eq 'report.txt' }
```

This will throw an exception if some code calls Set-Content on $path=$env:temp\test.txt less than 2 times
Only the calls where `-Path` was `report.txt` are counted. The assertion passes, because `Save-Report` wrote to that path.

### EXAMPLE 3

```powershell
Mock Set-Content {}
function Get-Weather ($City) {
Invoke-RestMethod -Uri "https://api.example.com/weather?city=$City"
}

{...
Some Code ...}
Mock Invoke-RestMethod

Should-Invoke Set-Content 0
Get-Weather -City 'Oslo'

Should-Invoke Invoke-RestMethod -Times 1 -Exactly -ParameterFilter { $Uri -match 'city=Oslo' }
```

This will throw an exception if some code calls Set-Content at all
Asserts that the weather API was queried exactly once, and that the request was made for the city of Oslo.

### EXAMPLE 4

```powershell
Mock Set-Content {}
```
Describe 'Save-Report' {
BeforeAll { Mock Set-Content }

\{...
Some Code ...\}
It 'writes exactly once per call' {
Save-Report -Path 'a.txt' -Content 'x'

Should-Invoke Set-Content -Exactly 2
Should-Invoke Set-Content -Times 1 -Exactly -Scope It
}
}
```

This will throw an exception if some code does not call Set-Content Exactly two times.
`-Scope It` counts only the calls made in the current `It` block, even though the mock is shared by the whole `Describe`.

### EXAMPLE 5

```powershell
Describe 'Should-Invoke Scope behavior' {
Mock Set-Content { }
Describe 'Publish-Thing' {
It 'writes from inside the module' {
Mock -ModuleName Toolbox Set-Content

It 'Calls Set-Content at least once in the It block' {
{...
Some Code ...}
Publish-Thing

Should-Invoke Set-Content -Exactly 0 -Scope It
Should-Invoke -ModuleName Toolbox Set-Content -Times 1 -Exactly
}
}
```

Checks for calls only within the current It block.
When the command under test lives in a module, both `Mock` and `Should-Invoke` must use the same `-ModuleName` so the recorded call is found.

### EXAMPLE 6

```powershell
Describe 'Describe' {
Mock -ModuleName SomeModule Set-Content { }

{...
Some Code ...}

It 'Calls Set-Content at least once in the Describe block' {
Should-Invoke -ModuleName SomeModule Set-Content
}
}
```
Mock Remove-Item

Checks for calls to the mock within the SomeModule module.
Note that both the Mock
and Should-Invoke commands use the same module name.
Remove-TempFile -Path "$env:TEMP/old.log"

### EXAMPLE 7

```powershell
Should-Invoke Get-ChildItem -ExclusiveFilter { $Path -eq 'C:\' }
Should-Invoke Remove-Item -ExclusiveFilter { $Path -like "$env:TEMP*" }
```

Checks to make sure that Get-ChildItem was called at least one time with
the -Path parameter set to 'C:\', and that it was not called at all with
the -Path parameter set to any other value.
`-ExclusiveFilter` passes only if *every* recorded call matches the filter. Here it asserts that `Remove-Item` was called at least once, and only ever for paths inside the temp folder. It is a shorthand for pairing a `Should-Invoke` and a `Should-NotInvoke`.

## PARAMETERS

Expand Down
16 changes: 12 additions & 4 deletions docs/commands/Should-MatchString.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,26 @@ The `-match` operator is case-insensitive by default, but you can make it case-s
### EXAMPLE 1

```powershell
"hello" | Should-MatchString "h.*o"
(New-Guid).Guid | Should-MatchString '^[0-9a-f-]{36}$'
```

This assertion will pass, because the actual value matches the regular expression pattern.
This assertion passes, because a GUID is made up of 36 lowercase hexadecimal and dash characters.

### EXAMPLE 2

```powershell
"hello" | Should-MatchString "H.*O" -CaseSensitive
'user-4f2a' | Should-MatchString '^user-[0-9a-f]{4}$'
```

This assertion will fail, because the actual value does not case-sensitively match the regular expression pattern.
This assertion passes, because the generated id matches the expected `user-` prefix followed by four hexadecimal characters. This is handy for checking that a function returns ids, tokens or file names in the format you expect.

### EXAMPLE 3

```powershell
'Pester 6.0.0' | Should-MatchString 'pester \d+\.\d+\.\d+' -CaseSensitive
```

This assertion fails, because with `-CaseSensitive` the lowercase `pester` in the pattern does not match the capitalized `Pester` in the actual value.

## PARAMETERS

Expand Down
21 changes: 14 additions & 7 deletions docs/commands/Should-NotHaveParameter.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,22 @@ It only checks the parameter name, unlike `Should-HaveParameter`, which can also
### EXAMPLE 1

```powershell
Get-Command "Invoke-WebRequest" | Should -NotHaveParameter Uri
Get-Command Get-Date | Should-NotHaveParameter Uri
```

This test fails, because it expected the parameter URI to not exist.
This assertion passes, because `Get-Date` has no `-Uri` parameter.

### EXAMPLE 2

```powershell
function Get-PublicReport {
param([string] $Name)
}
Get-Command Get-PublicReport | Should-NotHaveParameter Credential
```

This assertion passes, because `Get-PublicReport` does not expose a `-Credential` parameter. This is useful for guarding against accidentally adding parameters you want to keep off a command's public surface.

## PARAMETERS

Expand Down Expand Up @@ -106,11 +118,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
## NOTES
The attribute [ArgumentCompleter] was added with PSv5.
Previously this
assertion will not be able to use the -HasArgumentCompleter parameter
if the attribute does not exist.
## RELATED LINKS
[https://pester.dev/docs/commands/Should-NotHaveParameter](https://pester.dev/docs/commands/Should-NotHaveParameter)
Expand Down
100 changes: 25 additions & 75 deletions docs/commands/Should-NotInvoke.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -54,100 +54,50 @@ passed to Should-NotInvoke, Should-NotInvoke will throw an exception.
### EXAMPLE 1

```powershell
Mock Set-Content {}
```

\{...
Some Code ...\}
function Remove-TempFile ($Path, [switch] $WhatIf) {
if (-not $WhatIf) { Remove-Item -Path $Path }
}

Should-NotInvoke Set-Content
Describe 'Remove-TempFile' {
It 'does not delete anything in -WhatIf mode' {
Mock Remove-Item

This will throw an exception and cause the test to fail if Set-Content is not called in Some Code.

### EXAMPLE 2
Remove-TempFile -Path 'temp.txt' -WhatIf

```powershell
Mock Set-Content -parameterFilter {$path.StartsWith("$env:temp\")}
Should-NotInvoke Remove-Item
}
}
```

\{...
Some Code ...\}

Should-NotInvoke Set-Content 2 \{ $path -eq "$env:temp\test.txt" \}

This will throw an exception if some code calls Set-Content on $path=$env:temp\test.txt less than 2 times

### EXAMPLE 3

```powershell
Mock Set-Content {}
```

\{...
Some Code ...\}

Should-NotInvoke Set-Content 0

This will throw an exception if some code calls Set-Content at all
Because `-WhatIf` was passed, `Remove-TempFile` must not delete anything. The assertion passes when the mocked `Remove-Item` was never called, and throws (failing the test) if it was called.

### EXAMPLE 4
### EXAMPLE 2

```powershell
Mock Set-Content {}
```

\{...
Some Code ...\}

Should-NotInvoke Set-Content -Exactly 2
Mock Remove-Item

This will throw an exception if some code does not call Set-Content Exactly two times.
Remove-TempFile -Path "$env:TEMP/old.log"

### EXAMPLE 5

```powershell
Describe 'Should-NotInvoke Scope behavior' {
Mock Set-Content { }
Should-NotInvoke Remove-Item -ParameterFilter { $Path -notlike "$env:TEMP*" }
```

It 'Calls Set-Content at least once in the It block' \{
\{...
Some Code ...\}

Should-NotInvoke Set-Content -Exactly 0 -Scope It
\}
\}
Only the calls whose `-Path` is outside the temp folder are counted. The assertion passes, because `Remove-TempFile` only ever deletes inside `$env:TEMP`.

Checks for calls only within the current It block.

### EXAMPLE 6
### EXAMPLE 3

```powershell
Describe 'Describe' {
Mock -ModuleName SomeModule Set-Content { }
```

\{...
Some Code ...\}
Describe 'Remove-TempFile' {
BeforeAll { Mock Remove-Item }

It 'Calls Set-Content at least once in the Describe block' \{
Should-NotInvoke -ModuleName SomeModule Set-Content
\}
\}
It 'is a no-op in -WhatIf mode' {
Remove-TempFile -Path 'temp.txt' -WhatIf

Checks for calls to the mock within the SomeModule module.
Note that both the Mock
and Should-NotInvoke commands use the same module name.

### EXAMPLE 7

```powershell
Should-NotInvoke Get-ChildItem -ExclusiveFilter { $Path -eq 'C:\' }
Should-NotInvoke Remove-Item -Scope It
}
}
```

Checks to make sure that Get-ChildItem was called at least one time with
the -Path parameter set to 'C:\', and that it was not called at all with
the -Path parameter set to any other value.
`-Scope It` limits the check to calls made in the current `It` block, even when the mock is shared across the whole `Describe`.

## PARAMETERS

Expand Down
Loading