我对Pester很陌生,所以请多多包涵。我们正在尝试对一个很大的脚本进行测试,该脚本执行一些活动目录查询并验证数据。我将其简化为以下示例:

虚拟文件

Param (
    [String]$OU,
    [String[]]$Groups
)

$AllOUusers = Get-ADUser -Filter * -SearchBase $OU

$GroupMemberUsers = foreach ($G in $Groups) {
    Get-ADGroupMember $G -Recursive | Get-ADUser -Properties whenCreated
}


虚拟测试.ps1

$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来获取这些特定成员的更多详细信息。

最终目标是为第一个Mock返回所有用户帐户的Get-ADUser,并为Mock的第二个Get-ADUser仅根据组成员身份(或模拟组)返回特定的一组用户帐户成员资格)。

系统详情


PowerShell 5.1
酯4.1.1。
Windows Server 2012 R1
广告模块1.0.0.0。


unit-testing - 有和没有ParameterFilter的模拟Get-ADUser-LMLPHP

最佳答案

您正在看到的错误似乎正在发生,因为您在MockGet-ADGroupMember中创建的用户没有被映射到Identity参数,也不会被Identity参数接受,因为它接受管道输入ByValue并且期望使用ADUser类型宾语。

您可以通过使用New-MockObject创建所需的特定对象类型来解决此问题。这是Get-ADGroupMember模拟的替代选项:

Mock Get-ADGroupMember {
    1..2 | ForEach-Object {
        $User = New-MockObject -Type Microsoft.ActiveDirectory.Management.ADUser
        $User.SamAccountName = "Member$_"
        $User
    }
}


我已经使用ForEach作为返回之前返回的2个用户的快速方法,并使用您设置的值作为实际的ADUser对象。

但是,这实际上并不能使第二个-ParameterFilter上的Get-ADUser正常工作。似乎又是因为User是一个对象,但是您正在将它与字符串进行比较,所以它的值为true。

一个可能的解决方法(我认为对于您的特定用例有些起作用)不是检查$Identity的特定值,而是检查它是否具有任何值:

Mock Get-ADUser {
    [PSCustomObject]@{SamAccountName = 'User4'}
    [PSCustomObject]@{SamAccountName = 'User5'}
} -ParameterFilter { $identity }


这将导致在脚本中始终为第二个Get-ADUser调用第二个模拟,因为这是唯一通过管道传递身份值的代码。这并非您要实现的目标,但我认为可能会有所帮助。

08-26 23:13