简体   繁体   中英

Testing a powershell DSC script class with pester - Unable to find type [ClassName]

I am trying to test some custom DSC resources written as a class with the help of pester. However I am struggling to work out how to make the class available to a different file. This is not a pester issue really, I can not do this in powershell either. I have a module with a class in it much like the following in a SxDeployment.psm1 file

[DscResource()]
class SxWindowsService {
    [void]Set(){
    }
    [bool]Test(){
        return $true;
    }
    [SxWindowsService]Get(){
        return $this
    }
}

This module has a corresponding .psd1, which is listing the SxWindowsService class as a 'DscResourcesToExport'. It is being registered as a module, I can see this module when I do a Get-Module -ListAvailable and can also perform an Import-Module upon it.

I suppose my question really is how can I create aa reference to this class from another file?

Say I have a different file test.ps1 with the following

Import-Module SxDeployment

$class = [SxWindowsService]::new()

I get the following error, "Unable to find type [SxWindowsService]."

UPDATE After a little more tinkering, I can create an instance of the class by changing the .psm1 file to a .ps file and changing the import-module statement for . .\\SxDeployment.ps1. So it seems the problem is how do you consume resources defined in a DSC resource module file outside of a DSC configuration?

The type literal [SxWindowsService] won't be accessible outside the module. This is by design. Here is a quote from the release notes:

Class keyword >>> Defines a new class. This is a true .NET Framework type. Class members are public, but only public within the module scope. You can't refer to the type name as a string (for example, New-Object doesn't work), and in this release, you can't use a type literal (for example, [MyClass]) outside the script/module file in which the class is defined.

Edit:

Well after having said the above. Since there is a bit of a mismatch between object activation in .NET and PowerShell then I thought to myself, there might just be a way. And I found it:

Import-Module C:\ps\StackOverflow\32743812\issue.psm1 -Force
function New-PSClassInstance {
    param(
        [Parameter(Mandatory)]
        [String]$TypeName,
        [object[]]$ArgumentList = $null
    )
    $ts = [System.AppDomain]::CurrentDomain.GetAssemblies() |
        Where-Object Location -eq $null | 
            Foreach-Object {
                $_.Gettypes()
            } | Where-Object name -eq $TypeName |
                Select-Object -Last 1
    if($ts) {
        [System.Activator]::CreateInstance($ts,$ArgumentList )
    } else {
        $typeException = New-Object TypeLoadException $TypeName        
        $typeException.Data.Add("ArgumentList",$ArgumentList)
        throw $typeException
    }
}
New-PSClassinstance -TypeName SxWindowsService

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM