Я написал простой командлет PowerShell на C # , чтобы показать проблему, с которой я столкнулся. Не стесняйтесь клонировать репо, или раскошелиться на него и заставить его работать и отправить PR, или просто посмотрите на исходный код, чтобы точно узнать, что я делаю.
Я создал простой командлет PowerShell Core, используя пакет NuGet PowerShellStandard.Library . Я использую xUnit и пытаюсь запустить модульный тест для созданного командлета PowerShell. Проблема в том, что когда я вызываю метод .Invoke()
экземпляра командлета, он выдает NullReferenceException
.
Вот командлет, который я создал:
[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()
командлета, но этот класс, кажется, не существует в пакете PowerShellStandard.Library
NuGet, поэтому я предполагаю, что это не дружественный класс PowerShell Core. Другие блоги создают новое пространство выполнения и конвейер при каждом выполнении теста, но, опять же, у меня, похоже, нет функции CreatePipeline()
при использовании библиотеки PowerShellStandard.
Итак, мой вопрос, как я могу запустить xUnit-тесты на моем PowerShell Core Cmdlet
s, которые я создаю в C #, чтобы убедиться, что они функционируют должным образом?
Заранее спасибо!
Обновление
Использование версии .Net Framework System.Management.Automation.dll
не вызывает исключения при Invoke()
командлете, поэтому я решил определить мой проект модульного тестирования как проект .Net Framework вместо .Net ядро. Это позволило мне протестировать командлет, как и ожидалось, используя код, показанный в этом посте. Командлет все еще определен в проекте .Net Core и является кроссплатформенным, только модульные тесты - нет.
В настоящее время последняя версия пакета PowerShellStandard.Library
NuGet - 5.1.0, поэтому, надеюсь, эта проблема будет решена в следующей версии.