You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨模块调用PowerShell类时Pester测试参数绑定失败求助

问题原因及解决方案

核心原因

  1. 模块作用域隔离:PowerShell每个模块都有独立的运行作用域,MyModule内部加载的Person类,和测试脚本中单独加载的Person类是CLR层面的两个不同类型实例。即使类名完全一致,类型不兼容会导致参数绑定失败,触发看似“参数为null”的错误(实际是类型不匹配的误导性提示)。
  2. 类的导出规则:默认情况下,PowerShell模块不会自动导出定义的类。MyTypes模块没有显式导出Person类,导致MyModule只能在内部作用域访问该类,测试脚本加载的类无法和MyModule中的类形成关联。

解决方案

方案一:修改MyTypes模块显式导出类

修改MyTypes.psm1,添加类的导出逻辑:

class Person {
    [string] $Name
 
    Person([string] $name ) {
        $this.Name = $name
    }
}

# 显式导出Person类
Export-ModuleMember -Variable Person

修改MyModule.psm1,仅保留模块导入(无需using module):

Import-Module "C:\temp\StackOverflow\PSModules\MyTypes\MyTypes.psm1" -Force

function MyFunction {
    param (
        [Parameter(Mandatory = $true)]
        [Person] $person
    )
    Write-Output "Hello $($person.Name)"
}

Export-ModuleMember -Function MyFunction 

测试脚本只需导入MyModule,无需单独加载MyTypes:

BeforeAll {
    Import-Module "C:\temp\StackOverflow\PSModules\MyModule\MyModule.psm1" -Force
}
        
Describe 'MyFunction' {
        Mock Write-Output {}
        $person = [Person]::new("John Doe")

        It 'should call my function' {
            MyFunction -Person $person 
            Assert-MockCalled -CommandName Write-Output -Exactly 1 -Scope It 
        } 
}

方案二:从MyModule作用域获取Person类型(无需修改原模块)

如果不想改动MyTypes模块,可以通过MyModule的导出变量获取类实例:

BeforeAll {
    Import-Module "C:\temp\StackOverflow\PSModules\MyModule\MyModule.psm1" -Force
    # 从MyModule的导出变量中获取Person类型
    $personType = (Get-Module MyModule).ExportedVariables['Person'].Value
}
        
Describe 'MyFunction' {
        Mock Write-Output {}
        $person = $personType::new("John Doe")

        It 'should call my function' {
            MyFunction -Person $person 
            Assert-MockCalled -CommandName Write-Output -Exactly 1 -Scope It 
        } 
}

方案三:统一使用using module加载类

将MyTypes模块放到PowerShell的模块路径下(如$HOME\Documents\PowerShell\Modules\MyTypes),确保可以通过模块名直接引用。

修改MyModule.psm1:

using module MyTypes

function MyFunction {
    param (
        [Parameter(Mandatory = $true)]
        [Person] $person
    )
    Write-Output "Hello $($person.Name)"
}

Export-ModuleMember -Function MyFunction 

测试脚本顶部添加using module(必须在所有导入语句之前):

using module MyTypes

BeforeAll {
    Import-Module "C:\temp\StackOverflow\PSModules\MyModule\MyModule.psm1" -Force
}
        
Describe 'MyFunction' {
        Mock Write-Output {}
        $person = [Person]::new("John Doe")

        It 'should call my function' {
            MyFunction -Person $person 
            Assert-MockCalled -CommandName Write-Output -Exactly 1 -Scope It 
        } 
}

内容的提问来源于stack exchange,提问作者Kurtis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:53:21