An open API service indexing awesome lists of open source software.

https://github.com/verifytests/verify.nservicebus

Adds Verify support to verify NServiceBus Test Contexts
https://github.com/verifytests/verify.nservicebus

Last synced: about 1 year ago
JSON representation

Adds Verify support to verify NServiceBus Test Contexts

Awesome Lists containing this project

README

          

# Verify.NServiceBus

[![Discussions](https://img.shields.io/badge/Verify-Discussions-yellow?svg=true&label=)](https://github.com/orgs/VerifyTests/discussions)
[![Build status](https://ci.appveyor.com/api/projects/status/haolkpausmys1ur4?svg=true)](https://ci.appveyor.com/project/SimonCropp/Verify-NServiceBus)
[![NuGet Status](https://img.shields.io/nuget/v/Verify.NServiceBus.svg)](https://www.nuget.org/packages/Verify.NServiceBus/)

Adds [Verify](https://github.com/VerifyTests/Verify) support to verify NServiceBus.

**See [Milestones](../../milestones?state=closed) for release notes.**

## NuGet package

https://nuget.org/packages/Verify.NServiceBus/

## Usage


```cs
[ModuleInitializer]
public static void Initialize() =>
VerifyNServiceBus.Initialize();
```
snippet source | anchor

### Verifying a context

Given the following handler:


```cs
public class MyHandler :
IHandleMessages
{
public async Task Handle(MyRequest message, HandlerContext context)
{
await context.Publish(
new MyPublishMessage
{
Property = "Value"
});

await context.Reply(
new MyReplyMessage
{
Property = "Value"
});

var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(TimeSpan.FromHours(12));
await context.Send(
new MySendMessage
{
Property = "Value"
},
sendOptions);

await context.ForwardCurrentMessageTo("newDestination");
}
}
```
snippet source | anchor

The test that verifies the resulting context:


```cs
[Fact]
public async Task VerifyHandlerResult()
{
var handler = new MyHandler();
var context = new RecordingHandlerContext();

var message = new MyRequest();
await handler.Handle(message, context);

await Verify(context);
}
```
snippet source | anchor

The resulting verification file is as follows:


```txt
{
Forward: [
newDestination
],
Publish: [
{
MyPublishMessage: {
Property: Value
}
}
],
Reply: [
{
MyReplyMessage: {
Property: Value
}
}
],
Send: [
{
MySendMessage: {
Property: Value
},
Options: {
DeliveryDelay: 12:00:00
}
}
]
}
```
snippet source | anchor

#### Recording

Recording allows all message interaction with the test context to be captured and then verified.


```cs
[Fact]
public async Task VerifyHandlerResult()
{
Recording.Start();
var handler = new MyHandler();
var context = new RecordingHandlerContext();

var message = new MyRequest();
await handler.Handle(message, context);

await Verify("some other data");
}
```
snippet source | anchor

The resulting context verification file is as follows:


```txt
{
target: some other data,
message: [
{
Publish: {
MyPublishMessage: {
Property: Value
}
}
},
{
Reply: {
MyReplyMessage: {
Property: Value
}
}
},
{
Send: {
MySendMessage: {
Property: Value
},
Options: {
DeliveryDelay: 12:00:00
}
}
}
]
}
```
snippet source | anchor

#### Verifying a Saga

Given the following handler:


```cs
public class MySaga :
Saga,
IHandleMessages
{
protected override void ConfigureHowToFindSaga(SagaPropertyMapper mapper) =>
mapper.ConfigureMapping(message => message.OrderId)
.ToSaga(sagaData => sagaData.OrderId);

public async Task Handle(MyRequest message, HandlerContext context)
{
await context.Publish(
new MyPublishMessage
{
Property = "Value"
});

Data.MessageCount++;
}

public class MySagaData :
ContainSagaData
{
public Guid OrderId { get; set; }
public int MessageCount { get; set; }
}
}
```
snippet source | anchor

The test that verifies the resulting context:


```cs
[Fact]
public async Task VerifySagaResult()
{
var saga = new MySaga
{
Data = new()
};

var context = new RecordingHandlerContext();

var message = new MyRequest();
await saga.Handle(message, context);

await Verify(new
{
context,
saga
});
}
```
snippet source | anchor

The resulting verification file is as follows:


```txt
{
context: {
Publish: [
{
MyPublishMessage: {
Property: Value
}
}
]
},
saga: {
MessageCount: 1
}
}
```
snippet source | anchor

### Example behavior change

The next time there is a code change, that results in a different resulting interactions with NServiceBus, those changes can be visualized. For example if the `DelayDeliveryWith` is changed from 12 hours to 1 day:


```cs
await context.Publish(
new MyPublishMessage
{
Property = "Value"
});

await context.Reply(
new MyReplyMessage
{
Property = "Value"
});

var sendOptions = new SendOptions();
sendOptions.DelayDeliveryWith(TimeSpan.FromDays(1));
await context.Send(
new MySendMessage
{
Property = "Value"
},
sendOptions);

await context.ForwardCurrentMessageTo("newDestination");
```
snippet source | anchor

Then the resulting visualization diff would look as follows:

![visualization diff](/src/approvaltests-diff.png)

### Message to Handler mapping

`MessageToHandlerMap` allows verification of message that do not have a handler.

For example:


```cs
var map = new MessageToHandlerMap();
map.AddMessagesFromAssembly();
map.AddHandlersFromAssembly();
await Verify(map);
```
snippet source | anchor

Would result in:


```txt
{
MessagesWithNoHandler: [
MessageToHandlerMapTests.MessageWithNoHandler
]
}
```
snippet source | anchor

## Icon

[Approval](https://thenounproject.com/term/approval/1759519/) designed by [Mike Zuidgeest](https://thenounproject.com/zuidgeest/) from [The Noun Project](https://thenounproject.com/).