gpt4 book ai didi

c# - 如何测试自动命名状态机?

转载 作者:行者123 更新时间:2023-11-28 20:49:54 24 4
gpt4 key购买 nike

我正在尝试为自动命名状态机编写测试,但我在正确完成它时遇到了一些麻烦,而且我发现的文档很少。

这是我目前拥有的一项测试:

[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 调用找到匹配项,我希望所有消息都已处理,我应该能够获取我的状态机实例和已发布的事件并检查它们的值 - 但事实并非如此。当我在 fixture 中运行测试时,有时我得到的实例已经消耗并发布了预期的消息;有时它还不完全存在。

我尝试使用以下方式获取我的实例:

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( ... )没有成功 - 它超时了。 (我一直错误地假设超时会引发异常。)

最佳答案

对于遇到相同问题的任何人:您尝试获取实例的方式

var inst = _Saga.Sagas.FirstOrDefault(x => x.Saga.CorrelationId == sagaId);

可以这样固定

var instanceIds = await _sagaHarness.Match(
instance => instance.CorrelationId == sagaId
&& instance.CurrentState == _machine.Working.Name,
new TimeSpan(0, 0, 30));

将预期状态包含在条件中很重要。仅通过 correlationid 获取实例然后测试 CurrentState 可能会失败,因为设置状态(saga 执行是异步的)可能需要一些时间。查看完整示例 https://github.com/balintn22/AutomatonymousTestExample

关于c# - 如何测试自动命名状态机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50990945/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com