【问题标题】:Pester Test for scriptproperty return type脚本属性返回类型的 Pester 测试
【发布时间】:2020-04-02 18:21:57
【问题描述】:

我是新手,正在尝试为 PowerShell 类模块创建测试。我正在尝试确定如何测试我为我的类实现属性的特定方法。

我使用的基本结构是:

class TestClass {
    hidden [string] $_TestProp = $($this | Add-Member -MemberType ScriptProperty -Name TestProp -Value {
            return $this._TestProp
        } -SecondValue {
            param([string]$Value)
            $this._TestProp = $Value
        }
    )
}

这种结构虽然工作量更大,但确实让我能够在我的类中使用我认为“正常”的 getter\setter 功能。我要测试的是确保此属性是字符串类型。我尝试查看 Getter 脚本块的 AST,但找不到该脚本块的返回类型。

有人对我将如何测试脚本块的返回类型有任何想法吗?

更新

根据 cmets 的建议,我已经重写了这个类

class TestClass {
    hidden [string] $_TestProp 

    TestClass(){
        $this | Add-Member -MemberType ScriptProperty -Name TestProp -Value {
            return $this._TestProp
        } -SecondValue {
            param([string]$Value)
            $this._TestProp = $Value
        }
    }
}

从功能上讲,添加成员部分只是移动到构造函数区域而不是声明区域。

【问题讨论】:

  • 您不会通过使用该模式获得任何有价值的覆盖率统计数据,因为没有记者可以解开该特定模式;太多的魔法。您是否有理由为属性选择该路线,而不是仅使用方法或通过Add-Type 实现它并编写c# 会更简洁?
  • 看在你的 CPU 的份上,请将Add-Member 语句移到构造函数中!
  • @MathiasR.Jessen 你的观点很有道理。这种模式是我几年前在尝试实现特定目标时发现的,因为访问器和修改器不是 PowerShell 类的原生对象。由于我从未遇到过任何与性能相关的问题,因此我从未真正考虑过对其进行优化。根据你的 cmets,我已经相应地更新了我的模式
  • @MaximilianBurszley 我的 C# 技能有点过时了,这个问题只涉及一个更大项目的一小部分。用 C# 重写项目中的所有类目前超出了范围。

标签: powershell pester


【解决方案1】:

在做了一些额外的研究后,我想出了以下方法来获取我正在寻找的信息

$Instance = [TestClass]::new()
$PropName = "TestProp"
$PublicProp = $Instance.PSObject.Properties | Where-Object {$_.Name -eq "$($PropName)"}
$BackingProp = $Instance.PSObject.Properties["_$($PropName)"]
$BackingProp.TypeNameOfValue -eq $PublicProp.SetterScript.Ast.ParamBlock.Parameters.StaticType.FullName

这确保传入的 Setter 值与支持属性的类型相同

【讨论】:

    【解决方案2】:

    ScriptBlocks 没有类型签名,例如 C# 中的方法,因此您真正确定返回类型的唯一方法是调用它并查看返回的内容。

    即使这样,返回类型也可能在调用之间发生变化。比如下面脚本块的返回类型是什么?

    $myScriptBlock = {
        if( (Get-Random -Maximum 2) -gt 0 )
        {
            return 100;
        }
        else
        {
            return "aaa";
        }
    }
    

    ScriptBlock.Invoke 的正式定义说它在这里返回一个 Collection<PSObject> - https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.scriptblock.invoke?view=pscore-6.2.0 - 所以你可以说这是返回类型,但这并不能真正帮助你进行静态分析的 AST 来确定该集合是否包含单个字符串值或特定脚本块的其他内容...

    【讨论】:

    • 请看我建议的答案
    • 脚本块只是匿名函数。您可以像使用 Func<T, R>Action<T, R> 的任何其他对象一样对它们进行类型转换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多