Как выполнить модульное тестирование двоичного командлета PowerShell Core в C # - PullRequest
0 голосов
/ 21 июня 2019

Я написал простой командлет 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, поэтому, надеюсь, эта проблема будет решена в следующей версии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...