如何在 C# 中对 PowerShell Core 二进制 cmdlet 进行单元测试



我用C#编写了一个简单的PowerShell cmdlet来展示我遇到的问题。随意克隆存储库,或分叉它并使其工作并提交 PR,或者只是查看源代码以了解我在做什么。

我使用 PowerShellStandard.Library NuGet 包创建了一个简单的 PowerShell Core cmdlet。我正在使用 xUnit,并尝试针对我创建的 PowerShell cmdlet 运行单元测试。问题是当我调用 cmdlet 实例的.Invoke()方法时,它会抛出一个NullReferenceException.

下面是我创建的 cmdlet:

[Cmdlet(VerbsCommon.Get, "RepeatedString")]
[OutputType(typeof(string))]
public class GetRepeatedStringCmdlet : Cmdlet
{
[Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[Alias("Word")]
[ValidateNotNullOrEmpty()]
public string Phrase { get; set; }
[Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true)]
[Alias("Repeat")]
public int NumberOfTimesToRepeatPhrase { get; set; }
protected override void ProcessRecord()
{
base.ProcessRecord();
var result = new StringBuilder();
for (int i = 0; i < NumberOfTimesToRepeatPhrase; i++)
{
result.Append(Phrase);
}
WriteObject(result.ToString());
}
}

以下是我尝试运行的单元测试的示例:

[Fact]
public void ShouldReturnThePhraseRepeatedTheCorrectNumberOfTimes()
{
// Arrange.
var phrase = "A test phrase.";
int numberOfTimesToRepeat = 3;
var cmdlet = new GetRepeatedStringCmdlet()
{
Phrase = phrase,
NumberOfTimesToRepeatPhrase = numberOfTimesToRepeat
};
var expectedResult = Enumerable.Repeat(phrase, numberOfTimesToRepeat);
// Act.
var enumerator = cmdlet.Invoke().GetEnumerator(); // NullReferenceException thrown here when calling .Invoke().
Assert.True(enumerator.MoveNext());
var results = enumerator.Current;
// Assert.
Assert.Equal(results, expectedResult);
}

当我在PowerShell中测试脚本时,它似乎可以正常工作:

ImportModule .PowerShellCmdletInCSharpExample.dll
Get-RepeatedString -Phrase "Hello there" -NumberOfTimesToRepeatPhrase 3
Hello thereHello thereHello there

我正在遵循我在一些博客文章中找到的示例,例如这篇和这篇,但我想他们在调用.Invoke()时没有这个问题。其他博客文章(如本文)使用PsCmdletAssert类来.Invoke()cmdlet,但该类似乎不存在PowerShellStandard.LibraryNuGet 包中,所以我猜它不是一个 PowerShell Core 友好类。其他博客会在每次测试执行时创建一个新的运行空间和管道,但同样,在使用 PowerShellStandard 库时,我似乎没有CreatePipeline()函数。

所以我的问题是,如何针对我在 C# 中创建的 PowerShell CoreCmdlet运行 xUnit 测试,以验证它们按预期运行?

提前感谢!


更新

使用System.Management.Automation.dll的 .Net Framework 版本不会在Invoke()cmdlet 时引发异常,因此我的解决方法是将我的单元测试项目定义为 .Net Framework 项目,而不是 .Net Core。这使我能够使用本文中显示的代码按预期对 cmdlet 进行单元测试。该 cmdlet 仍在 .Net Core 项目中定义,并且是跨平台的,只有单元测试不是。

目前,PowerShellStandard.LibraryNuGet 包的最新版本是 5.1.0,因此希望在将来的版本中解决此问题。

我遇到了同样的问题。我能够通过将Microsoft.PowerShell.SDK安装到我的单元测试项目中来解决此问题,然后我的Cmdlet.Invoke()Powershell.Create()调用开始正常工作。

相关内容

  • 没有找到相关文章

最新更新