Awesome
<img src="/src/icon.png" height="30px"> Verify.MassTransit
Adds Verify support for MassTransit test helpers.
See Milestones for release notes.
NuGet package
https://nuget.org/packages/Verify.MassTransit/
Usage
<!-- snippet: enable --><a id='snippet-enable'></a>
[ModuleInitializer]
public static void Initialize() =>
VerifyMassTransit.Initialize();
<sup><a href='/src/Tests/ModuleInitializer.cs#L3-L9' title='Snippet source file'>snippet source</a> | <a href='#snippet-enable' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Consumer Test
Using traditional asserts consumer interactions can be tested as follows:
<!-- snippet: ConsumerTestAsserts --><a id='snippet-ConsumerTestAsserts'></a>
[Fact]
public async Task TestWithAsserts()
{
using var harness = new InMemoryTestHarness();
var consumerHarness = harness.Consumer<SubmitOrderConsumer>();
await harness.Start();
try
{
await harness.InputQueueSendEndpoint
.Send(
new SubmitOrder
{
OrderId = InVar.Id
});
// did the endpoint consume the message
Assert.True(await harness.Consumed.Any<SubmitOrder>());
// did the actual consumer consume the message
Assert.True(await consumerHarness.Consumed.Any<SubmitOrder>());
// the consumer publish the event
Assert.True(await harness.Published.Any<OrderSubmitted>());
// ensure that no faults were published by the consumer
Assert.False(await harness.Published.Any<Fault<SubmitOrder>>());
}
finally
{
await harness.Stop();
}
}
<sup><a href='/src/Tests/ConsumerTests.cs#L5-L38' title='Snippet source file'>snippet source</a> | <a href='#snippet-ConsumerTestAsserts' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Using Verify, the TestHarness and any number of ConsumerHarness, can be passed to Verify
.
<a id='snippet-ConsumerTestVerify'></a>
[Fact]
public async Task TestWithVerify()
{
using var harness = new InMemoryTestHarness();
var consumer = harness.Consumer<SubmitOrderConsumer>();
await harness.Start();
try
{
await harness.InputQueueSendEndpoint
.Send(
new SubmitOrder
{
OrderId = InVar.Id
});
await Verify(new
{
harness,
consumer
});
}
finally
{
await harness.Stop();
}
}
<sup><a href='/src/Tests/ConsumerTests.cs#L40-L70' title='Snippet source file'>snippet source</a> | <a href='#snippet-ConsumerTestVerify' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->The above will result in the following snapshot file that will need to be accepted.
<!-- snippet: ConsumerTests.TestWithVerify.verified.txt --><a id='snippet-ConsumerTests.TestWithVerify.verified.txt'></a>
{
harness: {
Messages: [
{
Sent: ConsumerTests.SubmitOrder,
MessageId: Guid_1,
ConversationId: Guid_2,
DestinationAddress: input_queue,
Message: {
OrderId: Guid_3
}
},
{
Received: ConsumerTests.SubmitOrder,
MessageId: Guid_1,
ConversationId: Guid_2,
DestinationAddress: input_queue,
Message: {
OrderId: Guid_3
}
},
{
Published: ConsumerTests.OrderSubmitted,
MessageId: Guid_4,
ConversationId: Guid_2,
DestinationAddress: Tests:ConsumerTests+OrderSubmitted,
Message: {
OrderId: Guid_3
}
}
]
},
consumer: {
Consumed: [
{
Received: ConsumerTests.SubmitOrder,
MessageId: Guid_1,
ConversationId: Guid_2,
DestinationAddress: input_queue,
Message: {
OrderId: Guid_3
}
}
]
}
}
<sup><a href='/src/Tests/ConsumerTests.TestWithVerify.verified.txt#L1-L46' title='Snippet source file'>snippet source</a> | <a href='#snippet-ConsumerTests.TestWithVerify.verified.txt' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Moving forward, any change in the message interactions will result in a new snapshot that can then be accepted or declines
Saga Test
The following Saga test:
<!-- snippet: SagaTests --><a id='snippet-SagaTests'></a>
[Fact]
public async Task Run()
{
using var harness = new InMemoryTestHarness();
var sagaHarness = harness.Saga<ConsumerSaga>();
var correlationId = NewId.NextGuid();
await harness.Start();
try
{
await harness.Bus.Publish(new Start {CorrelationId = correlationId});
await harness.Consumed.Any<Start>();
await Verify(new {harness, sagaHarness});
}
finally
{
await harness.Stop();
}
}
public class ConsumerSaga :
ISaga,
InitiatedBy<Start>
{
public Guid CorrelationId { get; set; }
public bool StartMessageReceived { get; set; }
public Task Consume(ConsumeContext<Start> context)
{
StartMessageReceived = true;
return Task.CompletedTask;
}
}
public class Start : CorrelatedBy<Guid>
{
public Guid CorrelationId { get; init; }
}
<sup><a href='/src/Tests/SagaTests.cs#L5-L47' title='Snippet source file'>snippet source</a> | <a href='#snippet-SagaTests' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Will result in the following snapshot file.
<!-- snippet: SagaTests.Run.verified.txt --><a id='snippet-SagaTests.Run.verified.txt'></a>
{
harness: {
Messages: [
{
Published: SagaTests.Start,
MessageId: Guid_1,
ConversationId: Guid_2,
DestinationAddress: Tests:SagaTests+Start,
Message: {
CorrelationId: Guid_3
}
},
{
Received: SagaTests.Start,
MessageId: Guid_1,
ConversationId: Guid_2,
DestinationAddress: Tests:SagaTests+Start,
Message: {
CorrelationId: Guid_3
}
}
]
},
sagaHarness: {
Consumed: [
{
Received: SagaTests.Start,
MessageId: Guid_1,
ConversationId: Guid_2,
DestinationAddress: Tests:SagaTests+Start,
Message: {
CorrelationId: Guid_3
}
}
],
Sagas: [
{
Saga: {
CorrelationId: Guid_3,
StartMessageReceived: true
},
ElementId: Guid_3
}
]
}
}
<sup><a href='/src/Tests/SagaTests.Run.verified.txt#L1-L46' title='Snippet source file'>snippet source</a> | <a href='#snippet-SagaTests.Run.verified.txt' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->Icon
Approval designed by SAM Designs from The Noun Project.