Simple IConsume<T> unit test with a mock

2,395 views
Skip to first unread message

Jens Pettersson

unread,
Apr 27, 2016, 10:34:29 AM4/27/16
to masstransit-discuss
Hello. I'm new to MassTransit and are currently exploring the possibility to unit test a consumer. The test scenario is as follows: 
  • A consumer receives a message that tells it to handle a product registration
  • The consumer should store the registration request in some kind of storage
The consumer has a dependency to an interface and all I want to do is to assert that the interface gets called. Terribly simple, but I fail to understand what type of Mass Transit test I should build for this simple scenario. After browsing the MT code base and looking at the unit tests there, this is what I came up with:

[TestFixture]
public class LabTests : InMemoryTestFixture
{
private IHandleProduct _handleProduct;

[SetUp]
public async void SetUp()
{
_handleProduct = A.Fake<IHandleProduct>();
await InputQueueSendEndpoint.Send<IRegisterProduct>(new { ProductId = "product-id"});
}

[Test]
public void Should_call_product_handler()
{
_handleProduct.CallsTo(x => x.Handle("product-id")).MustHaveHappened();
}

protected override void ConfigureInputQueueEndpoint(IInMemoryReceiveEndpointConfigurator configurator)
{
configurator.Consumer(() => new RegisterProductConsumer(_handleProduct));
}
}

This works... but not all the time. I assume this is due to the async nature of Mass Transit...

I can just try to test the consumer directly (i.e. no InMemoryTestFixture) but then I have to pass in a ConsumerContext<T> in the Consume(...) method. I can stub that as well, but it seems like a hack. 

The consume method is nothing more than this:

public Task Consume(ConsumeContext<IRegisterProduct> context)
{
//not async...
_handler.Handle(context.Message.ProductId);

return context.CompleteTask;
}

I might be missing something super simple here, and it bugs me. Probably something async related... Any ideas?

Thanks!

//J

Chris Patterson

unread,
Apr 27, 2016, 11:13:03 AM4/27/16
to masstrans...@googlegroups.com
The setup method cannot be async as NUnit doesn't support it. That's likely why it's unpredictable. 

__
Chris Patterson




--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/d3f5d761-ab5a-4019-b516-d36adefa0c22%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jens Pettersson

unread,
Apr 27, 2016, 11:23:45 AM4/27/16
to masstransit-discuss
Oh, I hope it's that simple. Will test when I get back to my client tomorrow.

I'm curious if that kind of test (the InMemoryTestFixture) is a preferred way of testing simple things like this or if there are other, more recommended, ways of doing it?

Thanks for the reply Chris!

//J
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

Chris Patterson

unread,
Apr 27, 2016, 3:38:48 PM4/27/16
to masstrans...@googlegroups.com
The InMemoryTestFixture is the best way to test consumers, since it does a full end-to-end test of the message, serialization, consumer, etc.


To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Jens Pettersson

unread,
Apr 27, 2016, 4:43:18 PM4/27/16
to masstransit-discuss
Thank you, Chris. Much appreciated!
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Marko Lahma

unread,
Apr 28, 2016, 1:18:49 AM4/28/16
to masstransit-discuss
Jens,

I recommend upgrading to NUnit 3 if possible when testing async code, it has scenarios better covered. https://github.com/nunit/docs/wiki/SetUp-Attribute : "SetUp methods may be async if running under .NET 4.0 or higher.". You can even get old NUnit 2 style XML output with a switch from console runner to keep builder servers happy.

And I also recommend creating a test that checks that there is no async void methods :)


Cheers,
Marko
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

Jens Pettersson

unread,
Apr 28, 2016, 2:36:38 AM4/28/16
to masstransit-discuss
Thank you Marko.

Alltough, I'm having a hard time running an 'InMemoryTestFixture' with NUnit3 and ReSharper (2016.1). The test just dissappears from the runner. Anyone know if the TestFramework for Mass Transit has issues with Nunit 3? The InMemoryTestFixture doesn't get picked up by the nunit3-console.exe runner for me as well :/

Sudhanshu Mishra

unread,
Apr 28, 2016, 2:46:00 AM4/28/16
to masstransit-discuss
Hi Jens,

From prior experience, ReSharper test runner does not like versions of NUnit prior to NUnit 3. If the MassTransit framework uses a lower version of NUnit, that may be the reason for tests to disappear.
You should still see the tests in the Test Explorer though..
cheers
Sud

Jens Pettersson

unread,
Apr 28, 2016, 3:08:54 AM4/28/16
to masstransit-discuss
Just an update, I downgraded to NUnit 2.6.4 as we're using it everywhere else (for example, the Akka.NET TestKit didn't support NUnit 3.x last time I checked and we're using it quite a bit in some of our projects). I changed the test to not use async in a setup (actually removed the setup completely in favour for a TestFixtureSetUp) and now the test works great. Every time.

Thanks for all the help guys. I appreciate it!

//J

Marko Lahma

unread,
Apr 28, 2016, 3:12:13 AM4/28/16
to masstransit-discuss

Unfortunately I'm not currently using InMemoryTestFixture, I've just picked some parts from test framework library without using the actual test cases / base classes. A quick and dirty way might be copy-pasting the InMemoryTestFixture as CustomInMemoryTestFixture to your code base and check whether it works better when it's targeted directly against your NUnit 3 version.

-Marko
Reply all
Reply to author
Forward
0 new messages