从控制台应用程序但不是从 NUnit 测试调用时库工作
Library working when called from Console app but not from NUnit test
我正在尝试为我正在处理的项目评估工作流库。可以在 github workflow-core.
找到该库
开始时,我试图构建一个简单的工作流程,它只是将一些文本写入文件。奇怪的是,当从控制台应用程序项目调用时,工作流工作正常。但是当我在 NUnit 测试和 运行 中使用相同的代码时,它不会向文件写入任何内容。
我在这里有点迷路,甚至不知道哪些细节对你们来说很重要,可以帮助我解决这个问题,但也许这可能是相关的?
- 工作流核心库基于 .NET 标准 2.0 构建
- NUnit项目和控制台项目均使用.NET Framework 4.7.2
- 工作流核心库使用各种任务(如任务并行库)的东西
- 工作流核心库是使用
Microsoft.Extensions.DependencyInjection
库 通过依赖注入构建的
这里是相关代码:
首先是工作流程 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
在该请求得到解决之前,您可以通过创建 ManualResetEvent
或 AutoResetEvent
并将其放在最后一个工作流步骤可以访问和调用 .Set()
的地方来帮助自己。您的测试应该通过调用 .WaitOne()
来等待它(这是阻塞的)。
另一个可能足够(但效率低下)的事件只是等待了足够长的时间:Thread.Sleep(2000)
等待两秒钟。请注意,即使在那之后,由于工作流执行器的异步性质,您的工作流也可能尚未完成。
我正在尝试为我正在处理的项目评估工作流库。可以在 github workflow-core.
找到该库开始时,我试图构建一个简单的工作流程,它只是将一些文本写入文件。奇怪的是,当从控制台应用程序项目调用时,工作流工作正常。但是当我在 NUnit 测试和 运行 中使用相同的代码时,它不会向文件写入任何内容。
我在这里有点迷路,甚至不知道哪些细节对你们来说很重要,可以帮助我解决这个问题,但也许这可能是相关的?
- 工作流核心库基于 .NET 标准 2.0 构建
- NUnit项目和控制台项目均使用.NET Framework 4.7.2
- 工作流核心库使用各种任务(如任务并行库)的东西
- 工作流核心库是使用
Microsoft.Extensions.DependencyInjection
库 通过依赖注入构建的
这里是相关代码: 首先是工作流程 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
在该请求得到解决之前,您可以通过创建 ManualResetEvent
或 AutoResetEvent
并将其放在最后一个工作流步骤可以访问和调用 .Set()
的地方来帮助自己。您的测试应该通过调用 .WaitOne()
来等待它(这是阻塞的)。
另一个可能足够(但效率低下)的事件只是等待了足够长的时间:Thread.Sleep(2000)
等待两秒钟。请注意,即使在那之后,由于工作流执行器的异步性质,您的工作流也可能尚未完成。