为何Context -ForEach的变量无法传递到It块?该如何修复?
解决Pester中
Context -ForEach变量无法传入InModuleScope的问题 问题根源
InModuleScope会创建独立的模块作用域,默认无法访问外部(Context -ForEach循环)的$Service变量,导致调用MyFunction时-Service参数为空,触发ValidateSet校验失败。
解决方案
方法1:通过-ArgumentList传递外部变量到InModuleScope
利用InModuleScope的-ArgumentList参数,将外部的$Service变量传入模块作用域内部,再通过param接收:
BeforeAll { Import-Module Pester Import-Module MyModule } Describe 'MyFunction' { BeforeAll { Mock -ModuleName MyModule Invoke-RestMethod { return @{ access_token = 'mocked access token' } } } Context 'When the service is <service>' -ForEach @( @{Service = 'MicrosoftGraph'} @{Service = 'SharePointOnline'} ) { It 'Should return an access token' { # 传递外部的$Service到InModuleScope内部 InModuleScope MyModule -ArgumentList $Service { param($Service) Mock New-GraphJwtAssertion {} $TenantId = '<tenantId>' $ClientId = '<clientId>' $Certificate = <certificate> $result = MyFunction -TenantId $TenantId -ClientId $ClientId -Certificate $Certificate -Service $Service $result | Should -Be 'mocked access token' } } } }
方法2:提前在模块作用域Mock私有函数
直接在Context的BeforeEach中,通过-ModuleName指定模块来Mock私有函数,避免进入InModuleScope,直接使用外部的$Service变量:
BeforeAll { Import-Module Pester Import-Module MyModule } Describe 'MyFunction' { BeforeAll { Mock -ModuleName MyModule Invoke-RestMethod { return @{ access_token = 'mocked access token' } } } Context 'When the service is <service>' -ForEach @( @{Service = 'MicrosoftGraph'} @{Service = 'SharePointOnline'} ) { BeforeEach { # 直接在模块作用域Mock私有函数 Mock -ModuleName MyModule New-GraphJwtAssertion {} } It 'Should return an access token' { $TenantId = '<tenantId>' $ClientId = '<clientId>' $Certificate = <certificate> $result = MyFunction -TenantId $TenantId -ClientId $ClientId -Certificate $Certificate -Service $Service $result | Should -Be 'mocked access token' } } }
方法对比
- 方法1适合需要在单个
It块内动态调整Mock逻辑的场景,灵活性更高。 - 方法2更简洁,减少了作用域切换的复杂度,推荐优先使用。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

