Unit testing 带和不带参数过滤器的模拟Get ADUser
我是个新手,所以请容忍我。我们正在尝试对一个非常大的脚本进行测试,该脚本执行一些active directory查询并验证数据。我将其简化为以下示例: Dummy.ps1Unit testing 带和不带参数过滤器的模拟Get ADUser,unit-testing,powershell,testing,pester,Unit Testing,Powershell,Testing,Pester,我是个新手,所以请容忍我。我们正在尝试对一个非常大的脚本进行测试,该脚本执行一些active directory查询并验证数据。我将其简化为以下示例: Dummy.ps1 Param ( [String]$OU, [String[]]$Groups ) $AllOUusers = Get-ADUser -Filter * -SearchBase $OU $GroupMemberUsers = foreach ($G in $Groups) { Get-ADGroupM
Param (
[String]$OU,
[String[]]$Groups
)
$AllOUusers = Get-ADUser -Filter * -SearchBase $OU
$GroupMemberUsers = foreach ($G in $Groups) {
Get-ADGroupMember $G -Recursive | Get-ADUser -Properties whenCreated
}
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
$Params = @{
OU = 'OU=users,DC=contoso,DC=com'
Groups = 'Group1', 'Group2'
}
Describe 'test' {
Mock Get-ADGroupMember {
[PSCustomObject]@{SamAccountName = 'Member1'}
[PSCustomObject]@{SamAccountName = 'Member2'}
}
Mock Get-ADUser {
[PSCustomObject]@{SamAccountName = 'User1'}
[PSCustomObject]@{SamAccountName = 'User2'}
[PSCustomObject]@{SamAccountName = 'User3'}
}
Mock Get-ADUser {
[PSCustomObject]@{SamAccountName = 'User4'}
[PSCustomObject]@{SamAccountName = 'User5'}
} -ParameterFilter {$identity -eq 'User1'}
."$here\$sut" @Params
it 'test 1' {
($AllOUusers | Measure-Object).Count | Should -BeExactly 3
}
it 'test 2' {
($GroupMemberUsers | Measure-Object).Count | Should -BeExactly 2
'User4', 'User5' | Should -BeIn $GroupMemberUsers.SamAccountName
}
}
虚拟测试.ps1
Param (
[String]$OU,
[String[]]$Groups
)
$AllOUusers = Get-ADUser -Filter * -SearchBase $OU
$GroupMemberUsers = foreach ($G in $Groups) {
Get-ADGroupMember $G -Recursive | Get-ADUser -Properties whenCreated
}
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
$Params = @{
OU = 'OU=users,DC=contoso,DC=com'
Groups = 'Group1', 'Group2'
}
Describe 'test' {
Mock Get-ADGroupMember {
[PSCustomObject]@{SamAccountName = 'Member1'}
[PSCustomObject]@{SamAccountName = 'Member2'}
}
Mock Get-ADUser {
[PSCustomObject]@{SamAccountName = 'User1'}
[PSCustomObject]@{SamAccountName = 'User2'}
[PSCustomObject]@{SamAccountName = 'User3'}
}
Mock Get-ADUser {
[PSCustomObject]@{SamAccountName = 'User4'}
[PSCustomObject]@{SamAccountName = 'User5'}
} -ParameterFilter {$identity -eq 'User1'}
."$here\$sut" @Params
it 'test 1' {
($AllOUusers | Measure-Object).Count | Should -BeExactly 3
}
it 'test 2' {
($GroupMemberUsers | Measure-Object).Count | Should -BeExactly 2
'User4', 'User5' | Should -BeIn $GroupMemberUsers.SamAccountName
}
}
错误:
Cannot validate argument on parameter 'Identity'.
在上面的例子中,我们首先尝试收集特定OU中的所有用户帐户,然后收集特定安全组的所有成员。当我们拥有这些成员时,我们再次使用Get-ADUser
CmdLet来获取这些特定成员的更多详细信息
最终目标是为第一个Get-ADUser
创建一个Mock
,返回所有用户帐户;第二个Get-ADUser
创建一个Mock
,只返回基于组成员身份(或模拟组成员身份)的特定用户帐户集
系统详细信息
- PowerShell 5.1
- 纠缠4.1.1
- Windows server 2012 R1
- AD模块1.0.0.0
您看到的错误似乎发生了,因为您在
Get-ADGroupMember
的Mock
中创建的用户没有映射到标识参数或被标识参数接受,因为它接受管道输入ByValue
,并且需要一个ADUser类型的对象
您可以通过使用newmockobject
创建所需的特定对象类型来解决此问题。这里有一个替代选项用于模拟获取ADGroupMember
:
Mock Get-ADGroupMember {
1..2 | ForEach-Object {
$User = New-MockObject -Type Microsoft.ActiveDirectory.Management.ADUser
$User.SamAccountName = "Member$_"
$User
}
}
我使用了一个ForEach
作为一种快速方法,返回您之前返回的2个用户,使用您设置的值,但作为实际的ADUser对象
但是,这实际上并不能使第二个上的-ParameterFilter
工作。这似乎又是因为用户是一个对象,但您将其与字符串进行比较时,它的计算结果不是真的
一种可能的解决方法(我认为对您的特定用例有一定的效果)不是检查$Identity
的特定值,而是检查它是否有任何值:
Mock Get-ADUser {
[PSCustomObject]@{SamAccountName = 'User4'}
[PSCustomObject]@{SamAccountName = 'User5'}
} -ParameterFilter { $identity }
这会导致脚本中的第二个Get ADUser
始终调用第二个Mock,因为这是唯一一个通过管道传输标识值的Mock。这并不是您想要实现的目标,但我想可能会有所帮助。您的代码对我有效,您使用的是什么版本的Pester?我刚刚用最新版本运行了它。您的test2失败是因为它返回12个结果,而不是2个,但这是正确的,因为它返回了两个组的两个用户,以及第一次get aduser调用找到的3个用户。谢谢Mark,非常感谢您的帮助。当我用你的例子替换我的代码时,我仍然有同样的错误。有没有可能发布一个完整的脚本,对你的工作结束?也许我们可以避免管道连接到Get ADUser
,这样带有-ParameterFiler
的Mock
就可以为匹配的单个SamAccountName
工作了?除了上面建议的更改之外,我的代码与您的代码完全相同,但令人好奇的是,即使在更改Mock
之前,我也没有发现您关于-Identity
的错误。唯一的区别是我在安装了AD PowerShell cmdlet的Win 7计算机上运行它。您是否尝试过在其他地方运行它?只是尝试了您的建议,并在另一台服务器上运行了代码,该服务器具有另一个操作系统(Win 2008)和另一个PowerShell版本(4.0)。恐怕还是一样的错误。。。无论如何,我都会帮你回答的。Thx标记