从控制台应用程序但不是从 NUnit 测试调用时库工作

Library working when called from Console app but not from NUnit test

我正在尝试为我正在处理的项目评估工作流库。可以在 github workflow-core.

找到该库

开始时,我试图构建一个简单的工作流程,它只是将一些文本写入文件。奇怪的是,当从控制台应用程序项目调用时,工作流工作正常。但是当我在 NUnit 测试和 运行 中使用相同的代码时,它不会向文件写入任何内容。

我在这里有点迷路,甚至不知道哪些细节对你们来说很重要,可以帮助我解决这个问题,但也许这可能是相关的?

这里是相关代码: 首先是工作流程 class:

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();
    }
}

如果能提供有关如何解决这个问题的任何线索,我将很高兴。

您能否尝试让 'var serviceCollection' 成为 ExplorationTests 的 class 成员。否则代码看起来没问题。

看起来您的测试在主机中启动了一个任务 运行ning,然后没有等待完成就退出了。一次性拆卸会立即 运行 并停止主机。

你不应该在没有等待任务完成的情况下结束测试。

工作流的执行是异步的,因此您必须等待某种表示完成的事件发生。 否则你的测试拆解将在工作流有机会做任何事情之前杀死主机。

此答案的第一个版本包含:

.Wait() 或其重载之一(允许指定最长等待时间)添加到 StartWorkflow 的结果以阻止测试,直到工作流完成。

不幸的是,这是错误的,因为 StartWorkflow returns 一个 Task 只产生工作流实例的 ID。解决此任务后,您的工作流程可能没有做任何有意义的事情。

GitHub 上有一个功能请求要求所需的功能:Wait for workflow to finish

在该请求得到解决之前,您可以通过创建 ManualResetEventAutoResetEvent 并将其放在最后一个工作流步骤可以访问和调用 .Set() 的地方来帮助自己。您的测试应该通过调用 .WaitOne() 来等待它(这是阻塞的)。

另一个可能足够(但效率低下)的事件只是等待了足够长的时间:Thread.Sleep(2000) 等待两秒钟。请注意,即使在那之后,由于工作流执行器的异步性质,您的工作流也可能尚未完成。