【发布时间】:2018-06-22 15:12:01
【问题描述】:
我正在尝试为 Automatonymous 状态机编写测试,但我在正确处理它时遇到了一些麻烦,而且我发现的文档很少。
这是我目前的一项测试:
[TestFixture]
public class MyProcessStateMachineTests
{
InMemoryTestHarness _Harness;
MyProcessStateMachine _Machine;
StateMachineSagaTestHarness<MyProcess, MyProcessStateMachine> _Saga;
[OneTimeSetUp]
public void ConfigureMessages()
{
MessageCorrelation.UseCorrelationId<RequestMyDetails>(x => x.CorrelationId);
MessageCorrelation.UseCorrelationId<FileAttached>(x => x.CorrelationId);
MessageCorrelation.UseCorrelationId<PDFGenerated>(x => x.CorrelationId);
MessageCorrelation.UseCorrelationId<CustomerAttachFile>(x => x.CorrelationId);
MessageCorrelation.UseCorrelationId<AddCustomerNote>(x => x.CorrelationId);
MessageCorrelation.UseCorrelationId<EmailPublished>(x => x.CorrelationId);
}
[SetUp]
public void InitializeTestHarness()
{
_Harness = new InMemoryTestHarness();
_Machine = new MyProcessStateMachine( /* snip */ );
_Saga = _Harness.StateMachineSaga<MyProcess, MyProcessStateMachine>(_Machine);
_Harness.Start().Wait();
}
[TearDown]
public void StopTestHarness()
{
_Harness.Stop();
}
[Test]
public async Task ShouldAttachToCustomer()
{
var sagaId = Guid.NewGuid();
var custId = Guid.NewGuid();
var fileAttached = BuildFileAttachedMessage(sagaId);
await _Harness.InputQueueSendEndpoint.Send(BuildStartMessage(sagaId));
await _Harness.InputQueueSendEndpoint.Send(BuildDetailsReceivedMessage(sagaId));
await _Harness.InputQueueSendEndpoint.Send(BuildPdfGeneratedMessage(sagaId));
await _Harness.InputQueueSendEndpoint.Send(fileAttached);
// Next line is based on [the answer here][1]
// Once the above messages are all consumed and processed,
// the state machine should be in AwaitingEmail state
await _Saga.Match(x =>
x.CorrelationId == sagaId
&& x.CurrentState == _Machine.AwaitingEmail.Name,
new TimeSpan(0, 0, 30));
// Grab the instance and Assert stuff...
}
// Snip...
}
鉴于 _Saga.Match 调用找到了匹配项,我希望所有消息都已处理,我应该能够获取我的状态机实例和已发布的事件并检查它们的值 - 但事实并非如此。当我在夹具中运行测试时,有时我得到的实例已经消耗并发布了预期的消息;有时它还没有完全到位。
我尝试使用以下方法获取我的实例:
var inst = _Saga.Sagas.FirstOrDefault(x => x.Saga.CorrelationId == sagaId);
或通过以下方式获取已发布的事件:
var test = _Harness.Published
.FirstOrDefault(x => x.MessageType == typeof(IAttachFile) && x.Context.CorrelationId == sagaId);
但是对 Match 的调用是否成功并不重要,状态机实例(和已发布的事件)并不总是存在。
我假设来自 Automatonymous、MassTransit 或测试工具的异步进程导致了不一致。有什么帮助吗?
使用 MassTransit、MassTransit.Automatonymous 和 MassTransit.TestFramework 5.1.2.1528、Automatonymous 4.1.1.102 进行测试,
编辑:
进一步审查,我发现当我遇到问题时,拨打Match( ... )
没有成功 - 它超时。 (我一直错误地认为超时会引发异常。)
【问题讨论】:
-
检查这些测试,它们实际上展示了如何使用测试工具来测试状态机传奇github.com/MassTransit/MassTransit/blob/develop/src/…
-
是的,我之前检查过这些测试。再试一次,以防我第一次错过了什么。使用基于 _Harness.Consumed 的检查,从 _Saga.Created 获取实例形式(如示例测试 Using_the_testing_framework_built_into_masstransit)。在调用和不调用 _Saga.Match 的情况下运行测试,在某些测试中使用断点进行调试,而不是在其他测试中。针对实例的当前 CurrentState 断言有时会通过,通常会失败。似乎在我只使用一两条消息的测试中更频繁地工作。如果我尝试进一步进入状态机,事情不会。
-
我会避免使用
MassTransit.TestFramework,因为它与 NUnit 耦合。我们正在使用MassTransit.Testing测试所有内容,没有任何问题。 -
@AlexeyZimarev MassTransit.Testing 还在吗?
-
对于遇到相同问题的任何人:您尝试获取实例的方式 var inst = _Saga.Sagas.FirstOrDefault(x => x.Saga.CorrelationId == sagaId);
标签: c# testing masstransit automatonymous