DSCResource.Tests/Tests/Unit/DscResource.Container.Tests.ps1
$projectRootPath = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent $moduleRootPath = Join-Path -Path $projectRootPath -ChildPath 'DscResource.Container' $modulePath = Join-Path -Path $moduleRootPath -ChildPath 'DscResource.Container.psm1' Import-Module -Name $modulePath -Force InModuleScope -ModuleName 'DscResource.Container' { <# Dynamically built scriptblock which variables inside are sent in the BeforeEach-block before the It-block that is using them for Mocks. #> $mockDockerInspectName = { return 'ContainerName' } $mockDockerInspectName_ParameterFilter = { $args[0] -eq 'inspect' ` -and $args[1] -eq $mockDynamicContainerIdentifer ` -and $args[2] -eq '--format' ` -and $args[3] -eq '{{.Name}}' } $mockDockerInspectState_ParameterFilter = { $args[0] -eq 'inspect' ` -and $args[1] -eq $mockDynamicContainerIdentifer ` -and $args[2] -eq '--format' ` -and $args[3] -eq '{{.State.Running}}' } $mockDockerInspectExitCode_ParameterFilter = { $args[0] -eq 'inspect' ` -and $args[1] -eq $mockDynamicContainerIdentifer ` -and $args[2] -eq '--format' ` -and $args[3] -eq '{{.State.ExitCode}}' } $mockDockerCpTo_ParameterFilter = { $args[0] -eq 'cp' ` -and $args[1] -eq $mockDynamicLocalPath ` -and $args[2] -eq ('{0}:{1}' -f $mockDynamicContainerIdentifer, $mockDynamicContainerPath) } $mockDockerCpFrom_ParameterFilter = { $args[0] -eq 'cp' ` -and $args[1] -eq ('{0}:{1}' -f $mockDynamicContainerIdentifer, $mockDynamicContainerPath) ` -and $args[2] -eq $mockDynamicLocalPath } $mockDockerLogs_ParameterFilter = { $args[0] -eq 'logs' ` -and $args[1] -eq $mockDynamicContainerIdentifer } $mockDockerStart_ParameterFilter = { $args[0] -eq 'start' ` -and $args[1] -eq $mockDynamicContainerIdentifer } $mockDockerImages_ParameterFilter = { $args[0] -eq 'images' ` -and $args[1] -eq '--format' ` -and $args[2] -eq '{{.Repository}}' } $mockDockerImagesWithTag_ParameterFilter = { $args[0] -eq 'images' ` -and $args[1] -eq '--format' ` -and $args[2] -eq '{{.Repository}}:{{.Tag}}' } $mockDockerPull_ParameterFilter = { $args[0] -eq 'pull' ` -and $args[1] -eq $mockDynamicContainerImageName } $mockDockerCreate_ParameterFilter = { $args[0] -eq 'create' ` -and $args[1] -eq '--name' ` -and $args[2] -eq $mockDynamicContainerName ` -and $args[3] -eq $mockDynamicContainerImageName ` -and $args[4] -eq 'powershell.exe' } Describe 'DscResource.Container\Write-PesterItBlock' { BeforeAll { Mock -CommandName 'Write-Host' $testCases = @( @{ Result = 'Passed' Name = 'TestPassed' Passed = $true }, @{ Result = 'Skipped' Name = 'TestSkipped' Passed = $true }, @{ Result = 'Failed' Name = 'TestFailed' Passed = $false } ) } Context 'When outputting an It-block' { It 'Should call the correct mocks for a <Result> It-block' -TestCases $testCases { param ( $Result, $Name, $Passed ) $mockTest = [PSCustomObject] @{ Result = $Result Name = $Name Passed = $Passed } Mock -CommandName 'It' -ParameterFilter { $Name -eq $mockTest.Name } { Write-PesterItBlock -TestResult $mockTest } | Should -Not -Throw $isSkipped = $false if ($mockTest.Result -eq 'Skipped') { $isSkipped = $true } Assert-MockCalled -CommandName 'It' -ParameterFilter { $Name -eq $mockTest.Name -and $Skip -eq $isSkipped } -Exactly -Times 1 -Scope It } } } Describe 'DscResource.Container\Out-TestResult' { BeforeAll { Mock -CommandName 'Write-Host' Mock -CommandName 'Start-Sleep' } Context 'When outputting an test results' { BeforeAll { $mockTest = [PSCustomObject] @{ Describe = 'MockedDescribeName' Passed = $true Result = 'Passed' Name = 'TestPassed' } } It 'Should call the correct mocks for the Describe-block without throwing' { Mock -CommandName 'Describe' -ParameterFilter { $Name -eq $mockTest.Describe } { Out-TestResult -TestResult $mockTest } | Should -Not -Throw Assert-MockCalled -CommandName 'Describe' -ParameterFilter { $Name -eq $mockTest.Describe } -Exactly -Times 1 -Scope It } } Context 'When outputting only failed test results' { BeforeAll { $mockTest = [PSCustomObject] @{ Describe = 'MockedDescribeName' Passed = $false Result = 'Passed' Name = 'TestPassed' } } It 'Should call the correct mocks for the Describe-block without throwing' { Mock -CommandName 'Describe' -ParameterFilter { $Name -eq $mockTest.Describe } { Out-TestResult -TestResult $mockTest -ShowOnlyFailed } | Should -Not -Throw Assert-MockCalled -CommandName 'Describe' -ParameterFilter { $Name -eq $mockTest.Describe } -Exactly -Times 1 -Scope It } } } Describe 'DscResource.Container\Start-ContainerTest' { Context 'When start test for a container' { BeforeAll { Mock -CommandName 'Write-Info' Mock -CommandName 'Start-Transcript' Mock -CommandName 'Stop-Transcript' Mock -CommandName 'Install-PackageProvider' Mock -CommandName 'Install-Module' Mock -CommandName 'Out-File' Mock -CommandName 'Invoke-Pester' -MockWith { @{ Passed = $true } } } Context 'When code coverage is used' { It 'Should start container test without throwing' { $startContainerTestParameters = @{ ContainerName = 'Dummy' Path = $TestDrive TestPath = Join-Path -Path $TestDrive -ChildPath 'Dummy.Tests.ps1' CodeCoverage = Join-Path -Path $TestDrive -ChildPath 'Dummy.ps1' } { Start-ContainerTest @startContainerTestParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'Start-Transcript' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Stop-Transcript' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Install-PackageProvider' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Install-Module' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Invoke-Pester' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Invoke-Pester' -Scope It -Exactly -Times 1 } } Context 'When code coverage is not used' { It 'Should start container test without throwing' { $startContainerTestParameters = @{ ContainerName = 'Dummy' Path = $TestDrive TestPath = Join-Path -Path $TestDrive -ChildPath 'Dummy.Tests.ps1' } { Start-ContainerTest @startContainerTestParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'Start-Transcript' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Stop-Transcript' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Install-PackageProvider' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Install-Module' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Invoke-Pester' -Scope It -Exactly -Times 1 Assert-MockCalled -CommandName 'Invoke-Pester' -Scope It -Exactly -Times 1 } } } } Describe 'DscResource.Container\Out-MissedCommand' { BeforeAll { $mockMissedCommand = @( [PSCustomObject] @{ File = '\TestFile1' # Extra backspace is a test. Function = 'TestFunction1' Line = '9999' Command = 'Command1' }, [PSCustomObject] @{ File = '\TestFile2' # Extra backspace is a test. Function = 'TestFunction2' Line = '8888' Command = 'Command2' } ) $mockTestOutputStringMissedCommand1 = ( '{0}\s*{1}\s*{2}\s*{3}' -f ` ($mockMissedCommand[0].File -replace '\\'), $mockMissedCommand[0].Function, $mockMissedCommand[0].Line, $mockMissedCommand[0].Command ) $mockTestOutputStringMissedCommand2 = ( '{0}\s*{1}\s*{2}\s*{3}' -f ` ($mockMissedCommand[1].File -replace '\\'), $mockMissedCommand[1].Function, $mockMissedCommand[1].Line, $mockMissedCommand[1].Command ) Mock -CommandName 'Write-Host' -MockWith { if ($Object -match $mockTestOutputStringMissedCommand1 ` -or $Object -match $mockTestOutputStringMissedCommand2) { $script:countNumberOfMissedCommandWritten += 1 } } } BeforeEach { $script:countNumberOfMissedCommandWritten = 0 } Context 'When test results contain missed commands' { It 'Should output the correct missed commands without throwing' { { Out-MissedCommand -MissedCommand $mockMissedCommand } | Should -Not -Throw $script:countNumberOfMissedCommandWritten | Should -Be 2 } } Context 'When test results contain missed commands and wait for AppVeyor console' { BeforeAll { Mock -CommandName 'Start-Sleep' } It 'Should output the correct missed commands without throwing' { { Out-MissedCommand -MissedCommand $mockMissedCommand -WaitForAppVeyorConsole -Timeout 55 } | Should -Not -Throw $script:countNumberOfMissedCommandWritten | Should -Be 2 Assert-MockCalled -CommandName 'Start-Sleep' -ParameterFilter { $Seconds -eq 55 } -Exactly -Times 1 -Scope It } } Context 'When test results does not contain missed commands (an empty array or $null value)' { It 'Should output the correct missed commands without throwing' { { Out-MissedCommand -MissedCommand $null } | Should -Not -Throw $script:countNumberOfMissedCommandWritten | Should -Be 0 Assert-MockCalled -CommandName 'Write-Host' -Exactly -Times 2 } } } Describe 'DscResource.Container\Copy-ItemToContainer' { BeforeAll { Mock -CommandName 'Write-Info' <# A placeholder/wrapper for the docker.exe so the code is tricked in to thinking it exists so that we can mock it. #> function docker { } Mock -CommandName 'docker' -MockWith $mockDockerInspectName ` -ParameterFilter $mockDockerInspectName_ParameterFilter Mock -CommandName 'docker' -ParameterFilter $mockDockerCpTo_ParameterFilter } AfterAll { Remove-Item -Path 'Function:\docker' } Context 'When copying item to a container' { BeforeAll { $mockIdentifier = '1A3' $mockPath = 'C:\' $mockDestination = 'D:\' $copyItemToContainerParameters = @{ ContainerIdentifier = $mockIdentifier Path = $mockPath Destination = $mockDestination } } BeforeEach { $mockDynamicContainerIdentifer = $mockIdentifier $mockDynamicLocalPath = $mockPath $mockDynamicContainerPath = $mockDestination } It 'Should copy the item without throwing' { { Copy-ItemToContainer @copyItemToContainerParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerCpTo_ParameterFilter -Exactly -Times 1 -Scope It } } } Describe 'DscResource.Container\Copy-ItemFromContainer' { BeforeAll { Mock -CommandName 'Write-Info' <# A placeholder/wrapper for the docker.exe so the code is tricked in to thinking it exists so that we can mock it. #> function docker { } Mock -CommandName 'docker' -MockWith $mockDockerInspectName ` -ParameterFilter $mockDockerInspectName_ParameterFilter Mock -CommandName 'docker' -ParameterFilter $mockDockerCpFrom_ParameterFilter } AfterAll { Remove-Item -Path 'Function:\docker' } Context 'When copying item from a container' { BeforeAll { $mockIdentifier = '1A3' $mockPath = 'D:\' $mockDestination = 'C:\' $copyItemToContainerParameters = @{ ContainerIdentifier = $mockIdentifier Path = $mockPath Destination = $mockDestination } } BeforeEach { $mockDynamicContainerIdentifer = $mockIdentifier $mockDynamicLocalPath = $mockDestination $mockDynamicContainerPath = $mockPath } It 'Should copy the item without throwing' { { Copy-ItemFromContainer @copyItemToContainerParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerCpFrom_ParameterFilter -Exactly -Times 1 -Scope It } } } Describe 'DscResource.Container\Get-ContainerLog' { BeforeAll { Mock -CommandName 'Write-Info' <# A placeholder/wrapper for the docker.exe so the code is tricked in to thinking it exists so that we can mock it. #> function docker { } Mock -CommandName 'docker' -MockWith $mockDockerInspectName ` -ParameterFilter $mockDockerInspectName_ParameterFilter Mock -CommandName 'docker' -MockWith { function New-ErrorRecord { param ( # Error message to return. [Parameter(Mandatory = $true)] [System.String] $Message ) return Write-Error -Message $Message 2>&1 } return @( New-ErrorRecord -Message 'MockedError1' New-ErrorRecord -Message 'MockedError2' ) } -ParameterFilter $mockDockerLogs_ParameterFilter } AfterAll { Remove-Item -Path 'Function:\docker' } Context 'When gathering the logs from a container' { BeforeAll { $mockIdentifier = '1A3' } BeforeEach { $mockDynamicContainerIdentifer = $mockIdentifier } It 'Should fetch the logs without throwing' { { Get-ContainerLog -ContainerIdentifier $mockIdentifier } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerLogs_ParameterFilter -Exactly -Times 1 -Scope It } } } Describe 'DscResource.Container\Wait-Container' { BeforeAll { $exitCode = 1 Mock -CommandName 'Write-Info' <# A placeholder/wrapper for the docker.exe so the code is tricked in to thinking it exists so that we can mock it. #> function docker { } Mock -CommandName 'docker' -MockWith $mockDockerInspectName ` -ParameterFilter $mockDockerInspectName_ParameterFilter } AfterAll { Remove-Item -Path 'Function:\docker' } Context 'When wait for a container to stop' { BeforeAll { $mockIdentifier = '1A3' Mock -CommandName 'Start-Sleep' Mock -CommandName 'docker' -MockWith { <# On the second hit on the mock this must return 'true' to be able to exit the do-until-loop. #> if ($script:dockerStateQueryHits -eq 0) { $script:dockerStateQueryHits += 1 return 'true' } else { return 'false' } } -ParameterFilter $mockDockerInspectState_ParameterFilter Mock -CommandName 'docker' -MockWith { return $exitCode } -ParameterFilter $mockDockerInspectExitCode_ParameterFilter } BeforeEach { $script:dockerStateQueryHits = 0 $mockDynamicContainerIdentifer = $mockIdentifier } It 'Should wait for the container until it is stopped without throwing' { { Wait-Container -ContainerIdentifier $mockIdentifier } | Should -Not -Throw Assert-MockCalled -CommandName 'Start-Sleep' -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectState_ParameterFilter -Exactly -Times 2 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectExitCode_ParameterFilter -Exactly -Times 1 -Scope It } } Context 'When the container fails to stop within the timeout period' { BeforeAll { $mockIdentifier = '1A3' Mock -CommandName 'docker' -MockWith { return 'true' } -ParameterFilter $mockDockerInspectState_ParameterFilter } BeforeEach { $mockDynamicContainerIdentifer = $mockIdentifier } It 'Should throw the correct error message' { $mockTimeout = 1 $errorMessage = $localizedData.ContainerTimeout -f $mockTimeout { Wait-Container -ContainerIdentifier $mockIdentifier -Timeout $mockTimeout } | Should -Throw $errorMessage Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectState_ParameterFilter -Exactly -Times 2 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectExitCode_ParameterFilter -Exactly -Times 0 -Scope It } } Context 'When the container throws an error when waiting for container to stop' { BeforeAll { $mockIdentifier = '1A3' $errorMessage = 'Something went wrong in the mock of docker inspect' Mock -CommandName 'docker' -MockWith { throw $errorMessage } -ParameterFilter $mockDockerInspectState_ParameterFilter } BeforeEach { $mockDynamicContainerIdentifer = $mockIdentifier } It 'Should throw the correct error message' { { Wait-Container -ContainerIdentifier $mockIdentifier } | Should -Throw $errorMessage Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectState_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectExitCode_ParameterFilter -Exactly -Times 0 -Scope It } } } Describe 'DscResource.Container\Start-Container' { BeforeAll { Mock -CommandName 'Write-Info' <# A placeholder/wrapper for the docker.exe so the code is tricked in to thinking it exists so that we can mock it. #> function docker { } Mock -CommandName 'docker' -MockWith $mockDockerInspectName ` -ParameterFilter $mockDockerInspectName_ParameterFilter Mock -CommandName 'docker' -MockWith $mockDockerInspectName ` -ParameterFilter $mockDockerStart_ParameterFilter } AfterAll { Remove-Item -Path 'Function:\docker' } Context 'When starting a container' { BeforeAll { $mockIdentifier = '1A3' } BeforeEach { $mockDynamicContainerIdentifer = $mockIdentifier } It 'Should start the container without throwing' { { Start-Container -ContainerIdentifier $mockIdentifier } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerInspectName_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerStart_ParameterFilter -Exactly -Times 1 -Scope It } } } Describe 'DscResource.Container\New-Container' { BeforeAll { $mockIdentifier = '1A3' $mockName = 'TestContainer' $mockImageName = 'microsoft/windowsservercore' $mockImageNameWithTag = 'microsoft/windowsservercore:1709' $mockImageNameWithLatestTag = 'microsoft/windowsservercore:latest' $mockTestPath = @('C:\Test1.Tests.ps1', 'C:\Test2.Tests.ps1') $mockCodeCoverage = @('C:\Test1.psm1', 'C:\Test2.psm1') } Context 'When creating a new container' { BeforeAll { # The file name never be 'StartTest.ps1'. $mockStartFilePath = Join-Path -Path $TestDrive -ChildPath 'MockFile.ps1' Mock -CommandName 'Write-Info' Mock -CommandName 'Copy-ItemToContainer' Mock -CommandName 'Out-File' -MockWith { $InputObject | Out-File $mockStartFilePath -Encoding ascii } -ParameterFilter { $FilePath -match 'StartTest\.ps1' } <# A placeholder/wrapper for the docker.exe so the code is tricked in to thinking it exists so that we can mock it. #> function docker { } Mock -CommandName 'docker' -ParameterFilter $mockDockerPull_ParameterFilter Mock -CommandName 'docker' -MockWith { return @('wrong images') } -ParameterFilter $mockDockerImages_ParameterFilter Mock -CommandName 'docker' -MockWith { return @('wrong images') } -ParameterFilter $mockDockerImagesWithTag_ParameterFilter Mock -CommandName 'docker' -MockWith { return $mockIdentifier } -ParameterFilter $mockDockerCreate_ParameterFilter } AfterAll { Remove-Item -Path 'Function:\docker' } Context 'When image does not contain a tag' { BeforeEach { $mockDynamicContainerName = $mockName $mockDynamicContainerImageName = $mockImageName } It 'Should create the container without throwing' { $newContainerParameters = @{ Name = $mockName ImageName = $mockImageName TestPath = $mockTestPath ProjectPath = $TestDrive CodeCoverage = $mockCodeCoverage } { New-Container @newContainerParameters } | Should -Not -Throw $mockStartFilePath | Should -Exist Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerImages_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerImagesWithTag_ParameterFilter -Exactly -Times 0 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerPull_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerCreate_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'Copy-ItemToContainer' -Exactly -Times 2 -Scope It Assert-MockCalled -CommandName 'Out-File' -Exactly -Times 1 -Scope It } Context 'When the container image already exists' { BeforeAll { Mock -CommandName 'docker' -MockWith { return @($mockImageName) } -ParameterFilter $mockDockerImages_ParameterFilter } It 'Should not pull the container image' { $newContainerParameters = @{ Name = $mockName ImageName = $mockImageName TestPath = $mockTestPath ProjectPath = $TestDrive CodeCoverage = $mockCodeCoverage } { New-Container @newContainerParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerPull_ParameterFilter -Exactly -Times 0 -Scope It } } } Context 'When image does not contain a tag' { BeforeEach { $mockDynamicContainerName = $mockName $mockDynamicContainerImageName = $mockImageNameWithTag } It 'Should create the container without throwing' { $newContainerParameters = @{ Name = $mockName ImageName = $mockImageNameWithTag TestPath = $mockTestPath ProjectPath = $TestDrive CodeCoverage = $mockCodeCoverage } { New-Container @newContainerParameters } | Should -Not -Throw $mockStartFilePath | Should -Exist Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerImages_ParameterFilter -Exactly -Times 0 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerImagesWithTag_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerPull_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerCreate_ParameterFilter -Exactly -Times 1 -Scope It Assert-MockCalled -CommandName 'Copy-ItemToContainer' -Exactly -Times 2 -Scope It Assert-MockCalled -CommandName 'Out-File' -Exactly -Times 1 -Scope It } Context 'When the container image already exists' { BeforeAll { Mock -CommandName 'docker' -MockWith { return @($mockImageNameWithTag) } -ParameterFilter $mockDockerImagesWithTag_ParameterFilter } It 'Should not pull the container image' { $newContainerParameters = @{ Name = $mockName ImageName = $mockImageNameWithTag TestPath = $mockTestPath ProjectPath = $TestDrive CodeCoverage = $mockCodeCoverage } { New-Container @newContainerParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerPull_ParameterFilter -Exactly -Times 0 -Scope It } } } Context 'When the container image already exist, but the tag is ''latest''' { BeforeAll { Mock -CommandName 'docker' -MockWith { return @($mockImageNameWithLatestTag) } -ParameterFilter $mockDockerImagesWithTag_ParameterFilter } BeforeEach { $mockDynamicContainerName = $mockName $mockDynamicContainerImageName = $mockImageNameWithLatestTag } It 'Should always pull the container image' { $newContainerParameters = @{ Name = $mockName ImageName = $mockImageNameWithLatestTag TestPath = $mockTestPath ProjectPath = $TestDrive CodeCoverage = $mockCodeCoverage } { New-Container @newContainerParameters } | Should -Not -Throw Assert-MockCalled -CommandName 'docker' ` -ParameterFilter $mockDockerPull_ParameterFilter -Exactly -Times 1 -Scope It } } } Context 'When Docker command does not exist' { BeforeAll { Mock -CommandName 'Get-Command' -MockWith { return $false } } It 'Should throw the correct error' { $newContainerParameters = @{ Name = $mockName ImageName = $mockImageName TestPath = $mockTestPath ProjectPath = $TestDrive CodeCoverage = $mockCodeCoverage } $errorMessage = $script:localizedData.DockerIsNotAvailable { New-Container @newContainerParameters } | Should -Throw $errorMessage } } } } |