Friday, 1 December 2017

Unit Test Fixtures

Almost ten years ago, I bought and read Gerard Meszaros’ xUnit Test Patterns, Refactoring Test Code. It is very comprehensive and seeks to document all the common test design patterns. Meszaros uses italics to indicate named patterns, and I'll follow that convention here.

The unit test framework I’ve used the most with .NET is NUnit. One quirk that I’m just beginning to understand better is the difference between Testcase Class and Fixture.

My confusion lies with how NUnit requires that classes which contain test methods, be decorated with the TestFixture attribute. I always assumed that this meant the class was "the fixture", but no!

Meszaros defines them as follows:
(I) use ‘test fixture’ or just ‘fixture’ to mean ‘the pre-conditions of the test’ and Testcase class to mean ‘the class that contains the Test Methods and any code needed to set up the test fixture’. (xUnit Test Patterns p.59)

The key thing is that while NUnit defaults to the Testcase Class per Fixture, you can do things differently.

Take a look at one of the unit test projects from the Cake project.
Cake.NuGet.Tests project structure


Notice how they’ve separated the Fixture classes and the Testcase classes into separate folders.

Here’s one of the test methods from the NuGetPackageInstallerTests class. Note how concise and uncomplicated it is. You can look at this method and very quickly understand what it’s testing.

[Fact]
public void Should_Be_Able_To_Install_If_Scheme_Is_Correct()
{
    // Given
    var fixture = new NuGetPackageInstallerFixture();
    fixture.Package = new PackageReference("nuget:?package=Cake.Core");

    // When
    var result = fixture.CanInstall();

    // Then
    Assert.True(result);
}

Now let’s look at the fixture class – NuGetPackageInstallerFixture

internal sealed class NuGetPackageInstallerFixture
{
    public ICakeEnvironment Environment { get; set; }
    public FakeFileSystem FileSystem { get; set; }
    public IProcessRunner ProcessRunner { get; set; }
    public INuGetToolResolver ToolResolver { get; set; }
    public INuGetContentResolver ContentResolver { get; set; }
    public ICakeLog Log { get; set; }

    public PackageReference Package { get; set; }
    public PackageType PackageType { get; set; }
    public DirectoryPath InstallPath { get; set; }

    public ICakeConfiguration Config { get; set; }

    public NuGetPackageInstallerFixture()
    {
        Environment = FakeEnvironment.CreateUnixEnvironment();
        FileSystem = new FakeFileSystem(Environment);
        ContentResolver = Substitute.For<INuGetContentResolver>();
        Log = Substitute.For<ICakeLog>();
        Config = Substitute.For<ICakeConfiguration>();

        ToolResolver = Substitute.For<INuGetToolResolver>();
        ToolResolver.ResolvePath().Returns(new FilePath("/Working/tools/nuget.exe"));

        Package = new PackageReference("nuget:https://myget.org/temp/?package=Cake.Foo&prerelease&version=1.2.3");
        PackageType = PackageType.Addin;
        InstallPath = new DirectoryPath("./nuget");

        ProcessRunner = Substitute.For<IProcessRunner>();
        ProcessRunner.When(p => p.Start(Arg.Any<FilePath>(), Arg.Any<ProcessSettings>()))
            .Do(info => FileSystem.CreateDirectory(InstallPath.Combine(Package.Package.ToLowerInvariant()).Combine(Package.Package)));
    }

    public void InstallPackageAtSpecifiedPath(DirectoryPath path)
    {
        ProcessRunner.When(p => p.Start(Arg.Any<FilePath>(), Arg.Any<ProcessSettings>()))
            .Do(info => FileSystem.CreateDirectory(path));
    }

    public NuGetPackageInstaller CreateInstaller()
    {
        return new NuGetPackageInstaller(FileSystem, Environment, ProcessRunner, ToolResolver, ContentResolver, Log, Config);
    }

    public IReadOnlyCollection<IFile> Install()
    {
        var installer = CreateInstaller();
        return installer.Install(Package, PackageType, InstallPath);
    }

    public bool CanInstall()
    {
        var installer = CreateInstaller();
        return installer.CanInstall(Package, PackageType);
    }
}

As described in xUnit Test Patterns, this Test Fixture has everything we need in place to exercise the SUT (system under test). It instantiates both the SUT and all its dependencies, and also provides helper methods that are called by the Test Methods. Without this, all of the setup and configuration code would have lived in the Testcase class (NuGetPackageInstallerTests). This looks like an example of the Transient Fresh Fixture pattern.

If you want to get another perspective on using test fixtures, I’d also recommend taking a look at Mark Seemann’s Advanced Unit Testing course on Pluralsight

Monday, 27 November 2017

Enterprise Service Bus libraries for .NET – Rebus

One in a series of posts giving a quick overview of ESB libraries for .NET

Rebus describes itself as "a lean service bus implementation for .NET".

https://github.com/rebus-org/Rebus

Messages

POCO classes

Publishing

Use an instance of IBus to publish.

activator is an implementation of IHandlerActivator - either BuiltinHandlerActivator or an adapter class for your particular IoC container.

activator.Bus.Publish(new DateTimeMessage(DateTime.Now)).Wait();

Subscribing

Handlers implement IHandleMessages<T>

public class PrintDateTime : IHandleMessages<DateTime>
{
    public async Task Handle(DateTime currentDateTime)
    {
        Console.WriteLine("The time is {0}", currentDateTime);
    }
}

And register a subscription

activator.Bus.Subscribe<StringMessage>().Wait();

Sunday, 26 November 2017

Enterprise Service Bus libraries for .NET – Shuttle ESB


One in a series of posts giving a quick overview of ESB libraries for .NET

Shuttle ESB describes itself as a "free .NET open-source enterprise service bus". It supports a good range of transports and integrates with a number of IoC containers.

https://github.com/Shuttle/shuttle-esb

Messages

A POCO class

Publishing

Publish using IServiceBus. You'll also make use of static methods from the ServiceBus class.

using (var bus = ServiceBus.Create(resolver).Start())
{
    bus.Publish(new MemberRegisteredEvent
    {
        UserName = "Mr Resistor"
    });
}

Subscribing

A handler implements IMessageHandler

public class MemberRegisteredHandler : IMessageHandler<MemberRegisteredEvent>
{
    public void ProcessMessage(IHandlerContext<MemberRegisteredEvent> context)
    {
        Console.WriteLine();
        Console.WriteLine("[EVENT RECEIVED] : user name = ‘{0}’", context.Message.UserName);
        Console.WriteLine();
    }
}

You also need to tell the subscription manager that you want to subscribe to a particular event. resolver is a wrapper class for your specific container.

resolver.Resolve<ISubscriptionManager>().Subscribe<MemberRegisteredEvent>();

Monday, 20 November 2017

Enterprise Service Bus libraries for .NET – Nimbus

One in a series of posts giving a quick overview of ESB libraries for .NET

Nimbus primarily supports the Azure Service Bus as a transport, so if your application is going to run in Azure, then this could be a good choice.

https://github.com/NimbusAPI/Nimbus/wiki/Publishing-an-Event-on-the-Bus

Messages

Event messages should implement IBusEvent

Publishing

Publish with an instance of IBus

_bus.Publish(new NewOrderReceived {CustomerName = "Ricky Bobby"});

Subscribing

Handle events by implementing IHandleMulticastEvent

public class ListenForNewOrders : IHandleMulticastEvent
{
 
    public async Task Handle(NewOrderReceived busEvent)
    {
        Console.WriteLine("I heard about a new order from " + busEvent.CustomerName);
 
        //Do more stuff
    }
}

Wednesday, 15 November 2017

Enterprise Service Bus libraries for .NET – MassTransit

One in a series of posts giving a quick overview of ESB libraries for .NET

MassTransit is an open-source library which apparently began as a response to some perceived deficiencies in the version of NServiceBus that was around in 2007. The project did a major rewrite in 2014, introducing async support and switching from MSMQ to RabbitMQ as the preferred transport.

Messages

Messages are POCO classes. There is no requirement to inherit from any base class or implement a specific interface.

Publishing

http://masstransit-project.com/MassTransit/usage/producing-messages.html

Messages are published using IPublishEndpoint, which is provided by ConsumeContext for consumers or by the IBus interface

public async Task NotifyOrderSubmitted(IPublishEndpoint publishEndpoint)
{
    await publishEndpoint.Publish<OrderSubmitted>(new
    {
        OrderId = "27",
        OrderDate = DateTime.UtcNow,
    });
}

Subscribing

http://masstransit-project.com/MassTransit/usage/message-consumers.html

A subscribing class (or consumer) implements the IConsumer<T> interface.
public class UpdateCustomerConsumer :
    IConsumer<UpdateCustomerAddress>
{
    public async Task Consume(ConsumeContext<UpdateCustomerAddress> context)
    {
        await Console.Out.WriteLineAsync($"Updating customer: {context.Message.CustomerId}");

        // update the customer address
    }
}

A consumer needs to be connected to an endpoint to receive messages

var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
    var host = cfg.Host(new Uri("rabbitmq://localhost/"), h =>
    {
        h.Username("guest");
        h.Password("guest");
    });

    cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
    {
        e.Consumer<UpdateCustomerConsumer>();
    });
});

Tuesday, 14 November 2017

Enterprise Service Bus libraries for .NET – NServiceBus

One in a series of posts giving a quick overview of ESB libraries for .NET

Originally an open-source library developed by Udi Dahan, the licensing was changed after version 2 to put it on a more commercial footing, and the software is now developed and supported by Udi’s company – Particular Software. The source code remains on Github.

NServiceBus is a tried and tested library. It has grown a lot since it's humble beginnings and now is once part of a suite of tools and libraries for building distributed applications. It's no surprise that Udi Dahan just happens to be highly regarded as an expert in distributed software architecture.

https://docs.particular.net/nservicebus/messaging/publish-subscribe/publish-handle-event

Messages

Messages need to either implement a marker interface or use defined conventions.
namespace Domain.Messages
{
  public class UserCreatedEvent : IEvent
  {
    public string Name { get; set; }
  }
}
Or
var conventions = endpointConfiguration.Conventions();

conventions.DefiningEventsAs(
 type =>

     {
       return type.Namespace == "MyNamespace.Messages.Events";
 });

Publishing

You can publish an event from within another handler or when you create an endpoint.
This example shows publishing an event from an endpoint:

var endpointInstance = await Endpoint.Start(endpointConfiguration)
    .ConfigureAwait(false);
    await endpointInstance.Publish(new MyEvent())
      .ConfigureAwait(false);

Subscribing

To handle an event, implement IHandleMessages<T>

public class UserCreatedHandler : IHandleMessages<UserCreatedEvent>
{
  public Task Handle(UserCreatedEvent message, IMessageHandlerContext context)
  { … }
}

NServiceBus will automatically locate handlers by looking for implementations of IHandleMessages<T>



Sunday, 5 November 2017

Enterprise Service Bus libraries for .NET

As a software application becomes larger, you may want to break it into separate parts, both to manage complexity but also to aid scalability. But if you break an application apart, how will the separate parts communicate? One approach is to employ messaging using a publish/subscribe (pub/sub) bus.

A few years ago, I worked on an application that used NServiceBus just for this purpose, but I thought it would be useful to survey the .NET landscape to find out what’s available today.

Here’s a summary of the libraries I’ll be looking at over the next few blog posts:

Name

URL

Transports

Minimum Framework

License

Dependencies

NServiceBus v6

https://docs.particular.net/nservicebus

Azure Service Bus, In-memory?, MSMQ, RabbitMQ, SQL Server

4.5.2

Commercial

-

MassTransit

http://masstransit-project.com/

Azure Service Bus, In-memory, RabbitMQ

4.5(.2?)

Apache 2.0

GreenPipes (>= 1.2.0)

NewId (>= 3.0.1)

Newtonsoft.Json (>= 10.0.3)

Newtonsoft.Json.Bson (>= 1.0.1)

NimbusAPI

https://github.com/NimbusAPI/Nimbus

Azure Service Bus

4.5

MIT

Microsoft.WindowsAzure.ConfigurationManager (= 2.0.3) Nimbus.InfrastructureContracts (>= 2.0.0.98)

Nimbus.MessageContracts (>= 2.0.0.98)

WindowsAzure.ServiceBus (>= 2.1.3 && <= 2.1.4)

Shuttle.Esb

http://shuttle.github.io/shuttle-esb/

MSMQ, RabbitMQ, SQL Server

4.0?

BSD 3

Shuttle.Core.Infrastructure (>= 8.0.6)

Rebus

https://github.com/rebus-org/Rebus

Azure Service Bus, MSMQ, RabbitMQ

4.5

MIT

Newtonsoft.Json (>= 9.0.1)

These libraries range from the relatively simple and tightly focused to the complete ‘enterprise-level’ configurable, extensible and/or fully supported.

Some of these libraries distinguish between an ‘event’ (notify subscribers that something has happened) and a ‘command’ (tell subscribers that they should perform an action). Some support long-running business processes, often known as ‘sagas’. Some support distributed transactions. Some use dependency injection and can integrate with an inversion-of-control container.

And because the feature sets vary so widely, I’ll just be highlighting how each library implements publishing an ‘event’ message, and how you subscribe to these messages.