Skip to content

Instantly share code, notes, and snippets.

@duongphuhiep
Created August 7, 2022 10:27
Show Gist options
  • Save duongphuhiep/15f223437bfd88a05de09c420473133b to your computer and use it in GitHub Desktop.
Save duongphuhiep/15f223437bfd88a05de09c420473133b to your computer and use it in GitHub Desktop.
Masstransit 8 TestHarness and Moq.Automocker
using MassTransit;
using MassTransit.Testing;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Moq.AutoMock;
using System.Threading.Tasks;
using Xunit;
namespace HiepTest;
public record SubmitOrder(long Id, string CustomerName);
public record OrderSubmitted(string SubmitReference);
public interface INotifier
{
public Task<string> Notify(string content);
}
public interface IStockChecker { }
public interface IFidelityUpdater { }
public interface IPromotionManager { }
public class SubmitOrderConsumer : IConsumer<SubmitOrder>
{
private readonly INotifier notifier;
public SubmitOrderConsumer(INotifier notifier, IStockChecker stockChecker, IFidelityUpdater fidelityUpdater, IPromotionManager promotionManager)
{
this.notifier = notifier;
}
public async Task Consume(ConsumeContext<SubmitOrder> context)
{
var input = context.Message;
await notifier.Notify("Order submitted");
var output = new OrderSubmitted($"{input.Id}.{input.CustomerName}");
await context.RespondAsync(output);
}
}
public class SampleUnitTest
{
/// <summary>
/// Treat the consumer as a normal class and unit test it.
/// </summary>
[Fact]
public async Task NormalTest()
{
//ARRANGE
AutoMocker mocker = new AutoMocker();
var consumerUnderTest = mocker.CreateInstance<SubmitOrderConsumer>();
mocker.GetMock<INotifier>().Setup(m => m.Notify(It.IsAny<string>())).ReturnsAsync("OK");
var sampleInput = new SubmitOrder(1, "Hiep");
var consumeContextMock = mocker.GetMock<ConsumeContext<SubmitOrder>>();
consumeContextMock.SetupGet(x => x.Message).Returns(sampleInput);
//ACT
await consumerUnderTest.Consume(consumeContextMock.Object);
//ASSERT
//that the customer is notified "Order submitted"
mocker.GetMock<INotifier>().Verify(m => m.Notify(It.Is<string>(v => v == "Order submitted")));
//that the response is sent back, and it contains the customer's name
consumeContextMock.Verify(m => m.RespondAsync(It.Is<OrderSubmitted>(r => r.SubmitReference.Contains(sampleInput.CustomerName))));
}
[Fact]
public async Task UseTestHarness()
{
//ARRANGE
AutoMocker mocker = new AutoMocker();
var consumerUnderTest = mocker.CreateInstance<SubmitOrderConsumer>();
await using var provider = new ServiceCollection()
.AddMassTransitTestHarness(cfg =>
{
cfg.AddConsumer<SubmitOrderConsumer>();
})
.AddSingleton(consumerUnderTest)
.BuildServiceProvider(true);
var harness = provider.GetRequiredService<ITestHarness>();
await harness.Start();
var client = harness.GetRequestClient<SubmitOrder>();
var sampleInput = new SubmitOrder(1, "Hiep");
//ACT
var response = await client.GetResponse<OrderSubmitted>(sampleInput);
//ASSERT
//that the sampleInput is consumed (there exist a SubmitOrder in the ReceivedMessageList)
Assert.True(await harness.Consumed.Any<SubmitOrder>());
Assert.True(await harness.Consumed.Any<SubmitOrder>(x => ((SubmitOrder)x.MessageObject).Id == sampleInput.Id));
//that the SubmitOrderConsumer is invoked (in case there are multiple Consumer)
var consumerHarness = harness.GetConsumerHarness<SubmitOrderConsumer>();
Assert.True(await consumerHarness.Consumed.Any<SubmitOrder>());
Assert.True(await consumerHarness.Consumed.Any<SubmitOrder>(x => ((SubmitOrder)x.MessageObject).Id == sampleInput.Id));
//that a response is sent back in the harness (there exist a OrderSubmitted in the SentMessageList)
Assert.True(await harness.Sent.Any<OrderSubmitted>());
Assert.True(await harness.Sent.Any<OrderSubmitted>(x => ((OrderSubmitted)x.MessageObject).SubmitReference.Contains(sampleInput.CustomerName)));
//that the customer is notified "Order submitted"
mocker.GetMock<INotifier>().Verify(m => m.Notify(It.Is<string>(v => v == "Order submitted")));
//that the response contains the customer's name
Assert.Contains(sampleInput.CustomerName, response.Message.SubmitReference);
}
}
@duongphuhiep
Copy link
Author

duongphuhiep commented Aug 8, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment