Indented.StubCommand
Indented.StubCommand copied to clipboard
Problem using Assert-MockCalled when dynamic parameter is using type from module
The stub cmdlet Move-ADDirectoryServer
passes a string in the parameter Site
. But the parameter Site
is of the type Microsoft.ActiveDirectory.Management.ADReplicationSite
which is a stub type.
When using an assert like below, the ToString()
method does not return anything, neither does $Site.Name
which is a property of the type Microsoft.ActiveDirectory.Management.ADReplicationSite
.
Example of assert that fails.
Assert-MockCalled -CommandName Move-ADDirectoryServer -Times 1 -ParameterFilter {
$Site.ToString() -eq $correctSiteName
}
The stub cmdlet looks like this.
function Move-ADDirectoryServer {
<#
.SYNOPSIS
Move-ADDirectoryServer [-Identity] <ADDirectoryServer> [-Site] <ADReplicationSite> [-WhatIf] [-Confirm] [-AuthType <ADAuthType>] [-Credential <pscredential>] [-Server <string>] [<CommonParameters>]
#>
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium', HelpUri='http://go.microsoft.com/fwlink/?LinkId=219321')]
param ( )
dynamicparam {
$parameters = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
# AuthType
$attributes = New-Object System.Collections.Generic.List[Attribute]
$attribute = New-Object System.Management.Automation.ParameterAttribute
$attributes.Add($attribute)
$parameter = New-Object System.Management.Automation.RuntimeDefinedParameter("AuthType", [Microsoft.ActiveDirectory.Management.ADAuthType], $attributes)
$parameters.Add("AuthType", $parameter)
# Credential
$attributes = New-Object System.Collections.Generic.List[Attribute]
$attribute = New-Object System.Management.Automation.ParameterAttribute
$attributes.Add($attribute)
$attribute = New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute
$attributes.Add($attribute)
$attribute = New-Object System.Management.Automation.CredentialAttribute
$attributes.Add($attribute)
$parameter = New-Object System.Management.Automation.RuntimeDefinedParameter("Credential", [System.Management.Automation.PSCredential], $attributes)
$parameters.Add("Credential", $parameter)
# Identity
$attributes = New-Object System.Collections.Generic.List[Attribute]
$attribute = New-Object System.Management.Automation.ValidateNotNullAttribute
$attributes.Add($attribute)
$attribute = New-Object System.Management.Automation.ParameterAttribute
$attribute.Position = 0
$attribute.Mandatory = $True
$attribute.ValueFromPipeline = $True
$attributes.Add($attribute)
$parameter = New-Object System.Management.Automation.RuntimeDefinedParameter("Identity", [Microsoft.ActiveDirectory.Management.ADDirectoryServer], $attributes)
$parameters.Add("Identity", $parameter)
# Server
$attributes = New-Object System.Collections.Generic.List[Attribute]
$attribute = New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute
$attributes.Add($attribute)
$attribute = New-Object System.Management.Automation.ParameterAttribute
$attributes.Add($attribute)
$parameter = New-Object System.Management.Automation.RuntimeDefinedParameter("Server", [System.String], $attributes)
$parameters.Add("Server", $parameter)
# Site
$attributes = New-Object System.Collections.Generic.List[Attribute]
$attribute = New-Object System.Management.Automation.ParameterAttribute
$attribute.Position = 1
$attribute.Mandatory = $True
$attributes.Add($attribute)
$attribute = New-Object System.Management.Automation.ValidateNotNullAttribute
$attributes.Add($attribute)
$parameter = New-Object System.Management.Automation.RuntimeDefinedParameter("Site", [Microsoft.ActiveDirectory.Management.ADReplicationSite], $attributes)
$parameters.Add("Site", $parameter)
return $parameters
}
end {
throw '{0}: StubNotImplemented' -f $MyInvocation.MyCommand
}
}
The stub type ADReplicationSite looks like this.
public class ADReplicationSite
{
// Constructor
public ADReplicationSite() { }
public ADReplicationSite(System.String identity) { }
public ADReplicationSite(System.Guid guid) { }
public ADReplicationSite(Microsoft.ActiveDirectory.Management.ADObject identity) { }
public ADReplicationSite(Microsoft.ActiveDirectory.Management.ADDirectoryServer directoryServer) { }
// Property
public System.String DistinguishedName { get; set; }
public System.String Name { get; set; }
public System.String ObjectClass { get; set; }
public System.Nullable<System.Guid> ObjectGuid { get; set; }
public System.Collections.ICollection PropertyNames { get; set; }
public System.Collections.Generic.ICollection<System.String> AddedProperties { get; set; }
public System.Collections.Generic.ICollection<System.String> RemovedProperties { get; set; }
public System.Collections.Generic.ICollection<System.String> ModifiedProperties { get; set; }
public System.Int32 PropertyCount { get; set; }
public Microsoft.ActiveDirectory.Management.ADPropertyValueCollection Item { get; set; }
}
So the above assert failed because ToString()
does not exist in the stub type, and $Site.Name does not contain the string value passed to the parameter
Site, of the cmdlet Move-ADDirectoryServer, because there are no logic in the stub class
ADReplicationSite` to handle that.
If I add logic to the class ADReplicationSite
constructor that takes a string as argument, and change the test code to assert on $Site.Name
then the assert works. I could have added the ToString()
method to return the Site.Name
property, but that is more uncertain if that is what the real ToString()
method does.
Changed logic in the class ADReplicationSite
. Just showing the relevant parts.
public class ADReplicationSite
{
// Constructor
...
public ADReplicationSite(System.String identity) { this.Name = identity; }
...
// Property
...
public System.String Name { get; set; }
...
}
Changed logic in the assert in the test.
Assert-MockCalled -CommandName Move-ADDirectoryServer -Times 1 -ParameterFilter {
$Site.Name -eq $correctSiteName
}
I don't think this one can be resolved? I thought I share my findings if someone else stumbles on the same problem, or if there are someone that can figure out a clever solution (other than manually change the code after the fact). 🙂