Tests/Unit/MSFT_SqlAgentAlert.Tests.ps1
<#
.SYNOPSIS Automated unit test for MSFT_SqlAgentAlert DSC resource. .NOTES To run this script locally, please make sure to first run the bootstrap script. Read more at https://github.com/PowerShell/SqlServerDsc/blob/dev/CONTRIBUTING.md#bootstrap-script-assert-testenvironment #> Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath '..\TestHelpers\CommonTestHelper.psm1') if (Test-SkipContinuousIntegrationTask -Type 'Unit') { return } $script:dscModuleName = 'SqlServerDsc' $script:dscResourceName = 'MSFT_SqlAgentAlert' #region HEADER # Unit Test Template Version: 1.2.0 $script:moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) if ( (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` (-not (Test-Path -Path (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) { & git @('clone', 'https://github.com/PowerShell/DscResource.Tests.git', (Join-Path -Path $script:moduleRoot -ChildPath '\DSCResource.Tests\')) } Import-Module (Join-Path -Path $script:moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force $TestEnvironment = Initialize-TestEnvironment ` -DSCModuleName $script:dscModuleName ` -DSCResourceName $script:dscResourceName ` -TestType Unit #endregion HEADER function Invoke-TestSetup { # Loading mocked classes } function Invoke-TestCleanup { Restore-TestEnvironment -TestEnvironment $TestEnvironment } # Begin Testing try { Invoke-TestSetup InModuleScope $script:dscResourceName { $mockServerName = 'localhost' $mockInstanceName = 'MSSQLSERVER' $mockSqlAgentAlertSevName = 'TestAlertSev' $mockSqlAgentAlertSeverity = '17' $mockSqlAgentAlertMsgName = 'TestAlertMsg' $mockSqlAgentAlertMessageId = '825' $mockInvalidOperationForCreateMethod = $false $mockInvalidOperationForDropMethod = $false $mockInvalidOperationForAlterMethod = $false $mockExpectedSqlAgentAlertToCreate = 'Sev16' $mockExpectedSqlAgentAlertToDrop = 'Sev18' # Default parameters that are used for the It-blocks $mockDefaultParameters = @{ InstanceName = $mockInstanceName ServerName = $mockServerName } #region Function mocks $mockConnectSQL = { return @( ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name InstanceName -Value $mockInstanceName -PassThru | Add-Member -MemberType NoteProperty -Name ComputerNamePhysicalNetBIOS -Value $mockServerName -PassThru | Add-Member -MemberType ScriptProperty -Name JobServer -Value { return (New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name Name -Value $mockServerName -PassThru | Add-Member -MemberType ScriptProperty -Name Alerts -Value { return ( New-Object -TypeName Microsoft.SqlServer.Management.Smo.Agent.Alert | Add-Member -MemberType NoteProperty -Name Name -Value $mockSqlAgentAlertSevName -PassThru -Force | Add-Member -MemberType NoteProperty -Name Severity -Value $mockSqlAgentAlertSeverity -PassThru -Force | Add-Member -MemberType NoteProperty -Name MessageId -Value 0 -PassThru -Force | Add-Member -MemberType ScriptMethod -Name Drop -Value { if ($mockInvalidOperationForDropMethod) { throw 'Mock Drop Method was called with invalid operation.' } if ( $this.Name -ne $mockExpectedSqlAgentAlertToDrop ) { throw "Called mocked Drop() method without dropping the right sql agent alert. Expected '{0}'. But was '{1}'." ` -f $mockExpectedSqlAgentAlertToDrop, $this.Name } } -PassThru -Force | Add-Member -MemberType ScriptMethod -Name Alter -Value { if ($mockInvalidOperationForAlterMethod) { throw 'Mock Alter Method was called with invalid operation.' } } -PassThru -Force ), ( New-Object -TypeName Microsoft.SqlServer.Management.Smo.Agent.Alert | Add-Member -MemberType NoteProperty -Name Name -Value $mockSqlAgentAlertMsgName -PassThru -Force | Add-Member -MemberType NoteProperty -Name Severity -Value 0 -PassThru -Force | Add-Member -MemberType NoteProperty -Name MessageId -Value $mockSqlAgentAlertMessageId -PassThru -Force | Add-Member -MemberType ScriptMethod -Name Drop -Value { if ($mockInvalidOperationForDropMethod) { throw 'Mock Drop Method was called with invalid operation.' } if ( $this.Name -ne $mockExpectedSqlAgentAlertToDrop ) { throw "Called mocked Drop() method without dropping the right sql agent alert. Expected '{0}'. But was '{1}'." ` -f $mockExpectedSqlAgentAlertToDrop, $this.Name } } -PassThru -Force | Add-Member -MemberType ScriptMethod -Name Alter -Value { if ($mockInvalidOperationForAlterMethod) { throw 'Mock Alter Method was called with invalid operation.' } if ($this.MessageId -eq 7) { throw "Called mocked Create() method for a message id that doesn't exist." } if ($this.Severity -eq 999) { throw "Called mocked Create() method for a severity that doesn't exist." } } -PassThru -Force ) } -PassThru ) } -PassThru -Force ) ) } $mockNewSqlAgentAlert = { return @( ( New-Object -TypeName Object | Add-Member -MemberType NoteProperty -Name Name -Value $mockSqlAgentAlertSevName -PassThru | Add-Member -MemberType ScriptMethod -Name Create -Value { if ($mockInvalidOperationForCreateMethod) { throw 'Mock Create Method was called with invalid operation.' } if ($this.Name -ne $mockExpectedSqlAgentAlertToCreate ) { throw "Called mocked Create() method without adding the right sql agent alert. Expected '{0}'. But was '{1}'." ` -f $mockExpectedSqlAgentAlertToCreate, $this.Name } if ($this.MessageId -eq 7) { throw "Called mocked Create() method for a message id that doesn't exist." } if ($this.Severity -eq 999) { throw "Called mocked Create() method for a severity that doesn't exist." } } -PassThru -Force ) ) } #endregion Describe "MSFT_SqlAgentAlert\Get-TargetResource" -Tag 'Get' { BeforeEach { Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable Mock -CommandName New-Object -MockWith $mockNewSqlAgentAlert -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Verifiable } Context 'When Connect-SQL returns nothing' { It 'Should throw the correct error' { Mock -CommandName Connect-SQL -MockWith { return $null } $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' } { Get-TargetResource @testParameters } | Should -Throw ($script:localizedData.ConnectServerFailed -f $testParameters.ServerName, $testParameters.InstanceName) } } Context 'When the system is not in the desired state' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'MissingAlert' } It 'Should return the state as absent' { $result = Get-TargetResource @testParameters $result.Ensure | Should -Be 'Absent' } It 'Should return the same values as passed as parameters' { $result = Get-TargetResource @testParameters $result.ServerName | Should -Be $testParameters.ServerName $result.InstanceName | Should -Be $testParameters.InstanceName } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 2 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 4 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Context 'When the system is in the desired state for a sql agent alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' } It 'Should return the state as present' { $result = Get-TargetResource @testParameters $result.Ensure | Should -Be 'Present' } It 'Should return the same values as passed as parameters' { $result = Get-TargetResource @testParameters $result.ServerName | Should -Be $testParameters.ServerName $result.InstanceName | Should -Be $testParameters.InstanceName $result.Name | Should -Be $testParameters.Name $result.Severity | Should -Be $mockSqlAgentAlertSeverity $result.MessageId | Should -Be 0 } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 2 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 4 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Assert-VerifiableMock } Describe "MSFT_SqlAgentAlert\Test-TargetResource" -Tag 'Test' { BeforeEach { Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable Mock -CommandName New-Object -MockWith $mockNewSqlAgentAlert -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Verifiable } Context 'When the system is not in the desired state and Ensure is set to Present' { It 'Should return the state as false when desired sql agent alert does not exist' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'MissingAlert' Severity = '25' Ensure = 'Present' } $result = Test-TargetResource @testParameters $result | Should -Be $false } It 'Should return the state as false when desired sql agent alert exists but has the incorrect severity' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Present' Severity = '25' } $result = Test-TargetResource @testParameters $result | Should -Be $false } It 'Should return the state as false when desired sql agent alert exists but has the incorrect message id' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Present' MessageId = '825' } $result = Test-TargetResource @testParameters $result | Should -Be $false } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 3 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 6 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Context 'When the system is not in the desired state and Ensure is set to Absent' { It 'Should return the state as false when non-desired sql agent alert exist' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Absent' } $result = Test-TargetResource @testParameters $result | Should -Be $false } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 1 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 2 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Context 'When the system is in the desired state and Ensure is set to Present' { It 'Should return the state as true when desired sql agent alert exist' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Present' } $result = Test-TargetResource @testParameters $result | Should -Be $true } It 'Should return the state as true when desired sql agent alert exists and has the correct severity' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Present' Severity = '17' } $result = Test-TargetResource @testParameters $result | Should -Be $true } It 'Should return the state as true when desired sql agent alert exists and has the correct message id' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertMsg' Ensure = 'Present' MessageId = '825' } $result = Test-TargetResource @testParameters $result | Should -Be $true } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 3 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 6 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Context 'When the system is in the desired state and Ensure is set to Absent' { It 'Should return the state as true when desired sql agent alert does not exist' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'MissingAlert' Ensure = 'Absent' } $result = Test-TargetResource @testParameters $result | Should -Be $true } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 1 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 2 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Assert-VerifiableMock } Describe "MSFT_SqlAgentAlert\Set-TargetResource" -Tag 'Set' { BeforeEach { Mock -CommandName Connect-SQL -MockWith $mockConnectSQL -Verifiable Mock -CommandName New-Object -MockWith $mockNewSqlAgentAlert -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Verifiable } Context 'When Connect-SQL returns nothing' { It 'Should throw the correct error' { Mock -CommandName Get-TargetResource -Verifiable Mock -CommandName Connect-SQL -MockWith { return $null } $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'Message7' Ensure = 'Present' } { Set-TargetResource @testParameters } | Should -Throw ($script:localizedData.ConnectServerFailed -f $testParameters.ServerName, $testParameters.InstanceName) } } Context 'When the system is not in the desired state and Ensure is set to Present'{ It 'Should not throw when creating the sql agent alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Present' } { Set-TargetResource @testParameters } | Should -Not -Throw } It 'Should not throw when changing the severity' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Present' Severity = '17' } { Set-TargetResource @testParameters } | Should -Not -Throw } It 'Should not throw when changing the message id' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertMsg' Ensure = 'Present' MessageId = '825' } { Set-TargetResource @testParameters } | Should -Not -Throw } It 'Should throw when changing severity and message id' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertMsg' Ensure = 'Present' Severity = '17' MessageId = '825' } { Set-TargetResource @testParameters } | Should -Throw } It 'Should throw when message id is not valid when altering existing alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertMsg' Ensure = 'Present' MessageId = '7' } { Set-TargetResource @testParameters } | Should -Throw } It 'Should throw when severity is not valid when altering existing alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertMsg' Ensure = 'Present' Severity = '999' } { Set-TargetResource @testParameters } | Should -Throw } It 'Should throw when message id is not valid when creating alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'NewAlertMsg' Ensure = 'Present' MessageId = '7' } { Set-TargetResource @testParameters } | Should -Throw } It 'Should throw when severity is not valid when creating alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'NewAlertMsg' Ensure = 'Present' Severity = '999' } { Set-TargetResource @testParameters } | Should -Throw } $mockInvalidOperationForCreateMethod = $true It 'Should throw the correct error when Create() method was called with invalid operation' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'NewAlert' Ensure = 'Present' } $errorMessage = ($script:localizedData.CreateAlertSetError -f $testParameters.Name, $testParameters.ServerName, $testParameters.InstanceName) { Set-TargetResource @testParameters } | Should -Throw $errorMessage } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 9 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 21 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Context 'When the system is not in the desired state and Ensure is set to Absent' { It 'Should not throw when dropping the sql agent alert' { $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'Sev16' Ensure = 'Absent' } { Set-TargetResource @testParameters } | Should -Not -Throw } It 'Should throw the correct error when Drop() method was called with invalid operation' { $mockInvalidOperationForDropMethod = $true $testParameters = $mockDefaultParameters $testParameters += @{ Name = 'TestAlertSev' Ensure = 'Absent' } $errorMessage = ($script:localizedData.DropAlertSetError -f $testParameters.Name, $testParameters.ServerName, $testParameters.InstanceName) { Set-TargetResource @testParameters } | Should -Throw $errorMessage } It 'Should call the mock function Connect-SQL' { Assert-MockCalled -CommandName Connect-SQL -Exactly -Times 2 -Scope Context } It 'Should call the mock function New-Object with TypeName equal to Microsoft.SqlServer.Management.Smo.Agent.Alert' { Assert-MockCalled -CommandName New-Object -Exactly -Times 4 -ParameterFilter { $TypeName -eq 'Microsoft.SqlServer.Management.Smo.Agent.Alert' } -Scope Context } } Assert-VerifiableMock } } } finally { Invoke-TestCleanup } |