Библиотека работает при вызове из консольного приложения, но не из теста NUnit - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь оценить библиотеку рабочих процессов для проекта, над которым я работаю.Библиотеку можно найти по адресу github workflow-core .

Для начала я пытался создать простой рабочий процесс, который просто записывает некоторый текст в файл.Любопытно, что рабочий процесс работает нормально при вызове из проекта консольного приложения.Но когда я использую тот же код в тесте NUnit и запускаю его, он ничего не записывает в файл.

Я немного растерялся и даже не знаю, какие детали важны для вас, ребята, чтобы помочь мне разобраться в этом, но, возможно, это может иметь отношение?

  • Библиотека workflow-core построена на стандарте .NET 2.0
  • Проект NUnit и консольный проект используют .NET Framework 4.7.2
  • В библиотеке workflow-core используются все виды задач(как в Task Parallel Library) stuff
  • Библиотека workflow-core создается с внедрением зависимостей с использованием библиотеки Microsoft.Extensions.DependencyInjection

И вот соответствующий код: Сначала класс рабочего процесса:

public class HelloWorldWorkflow : IWorkflow
{
    public string Id => nameof(HelloWorldWorkflow);
    public int Version => 1;
    public void Build(IWorkflowBuilder<object> builder)
    {
        builder.StartWith((context) =>
        {
            File.WriteAllText(@"C:\Test\test.txt", "Test line worked!");
            return ExecutionResult.Next();
        });
    }
}

Код вызова из консольного приложения (работает):

class Program
{
    static void Main(string[] args)
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddLogging((config) => config.AddConsole());
        serviceCollection.AddWorkflow();

        serviceCollection.AddTransient<LogStep>();

        var serviceProvider = serviceCollection.BuildServiceProvider();

        var host = serviceProvider.GetService<IWorkflowHost>();
        host.RegisterWorkflow<HelloWorldWorkflow>();

        host.Start();

        host.StartWorkflow(nameof(HelloWorldWorkflow));

        Console.WriteLine("Done");
        Console.ReadLine();

        host.Stop();
    }
}

И код из моего тестового проекта (не работает):

[TestFixture]
public class ExplorationTests
{
    private ServiceProvider _serviceProvider;
    private IWorkflowHost _host;

    [OneTimeSetUp]
    public void Init()
    {
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddLogging((config) => config.AddConsole());
        serviceCollection.AddWorkflow();

        serviceCollection.AddTransient<LogStep>();
        serviceCollection.AddTransient<HelloWorldWorkflow>();

        _serviceProvider = serviceCollection.BuildServiceProvider();

        _host = _serviceProvider.GetService<IWorkflowHost>();
        _host.RegisterWorkflow<HelloWorldWorkflow>();

        _host.Start();
    }

    [Test]
    public void Test()
    {
        _host.StartWorkflow(nameof(HelloWorldWorkflow));

    }

    [OneTimeTearDown]
    public void TearDown()
    {
        _host.Stop();
    }
}

Я был бы рад любым подсказкам о том, как это выяснить.

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Похоже, ваш тест запускает задачу, выполняющуюся на хосте, а затем завершает свою работу, не дожидаясь завершения.Затем однократный разбор запускается немедленно и останавливает хост.

Не следует завершать тест, не дожидаясь завершения задачи.

0 голосов
/ 17 декабря 2018

Выполнение рабочих процессов происходит асинхронно, поэтому вы должны ждать какого-то события, которое сигнализирует о завершении.В противном случае тестовый демонтаж убьет хост до того, как рабочий процесс сможет что-либо сделать.

Первая версия этого ответа содержала:

Добавление .Wait() или одну из его перегрузок (которые позволяют указатьмаксимальное время ожидания) до результата StartWorkflow, чтобы заблокировать тест до завершения рабочего процесса.

К сожалению, это неправильно, поскольку StartWorkflow возвращает Task, получая только идентификатор экземпляра рабочего процесса.Когда эта задача решена, ваш рабочий процесс, вероятно, не сделал ничего значимого.

В GitHub есть запрос функции, запрашивающий нужную функцию: Ожидание завершения рабочего процесса

Пока этот запрос не будет решен, вы можете помочь себе, создав ManualResetEvent или, возможно, AutoResetEvent и поместив его куда-нибудь, к которому вы можете получить доступ к вашему последнему шагу рабочего процесса, и вызовите .Set() для него.Ваш тест должен дождаться этого, вызвав на нем .WaitOne() (это блокировка).

Еще одно событие, которое может быть достаточным (но неэффективным), - это просто ожидание достаточно большой продолжительности: Thread.Sleep(2000) ждет две секунды,Помните, что даже после этого возможно, что ваш рабочий процесс не завершен из-за асинхронного характера исполнителя рабочего процесса.

0 голосов
/ 17 декабря 2018

Можете ли вы попробовать, сделав 'var serviceCollection' членом класса ExplorationTests.В противном случае код выглядит нормально.

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