Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Unit Test Complex Handler Network

I have a reasonably complex program architecture with minimal logic but lots of event handler passing. I'm making a skeleton of a server framework, and I have the following classes:

Core, which listens to:

CommHandler, which listens to:

CommLayer, which listens to:

IServerMock, which I stub out with a mocking framework (MOQ).

What's the best way to unit test relationships like this that are triggered by events? I know unit tests are supposed to be very isolated and granular things, but the only way I can think of testing this is by testing the entire process and checking the final output from Core.

like image 525
sichinumi Avatar asked Aug 23 '26 18:08

sichinumi


2 Answers

You need to make an abstraction for each class so Core depends on an ICommHandler not CommHandler and so-on. The dependencies should be supplied via the constructor and that way you can easily test each class in isolation as you can mock it's dependancies.

public class Core
{
    private ICommHandler commHandler;

    public Core(ICommHandler commHandler)
    {
        this.commHandler = commHandler;
    }
}

In your production code you can then do this:

var core = new Core(new CommHandler());

Although it would be better to use an IOC container to manage the instantiation of the objects since CommHandler has it's own dependencies but you should look into that separately.

Then in your Unit Test, you can do this:

[Test]
public void TestSomeCommHandlerEvent()
{
     var mockCommHandler = new Mock<ICommHandler>();
     // set up the mock

     var core = new Core(mockCommHandler.Object);
}

Doing this allows you to replace the implementation of ICommHandler in your test with a mock which you can configure the behaviour of.

like image 114
Trevor Pilley Avatar answered Aug 25 '26 07:08

Trevor Pilley


Sounds like you can just mock the events and check that the listener performs the correct action (ie, invokes its own event). For example:

// Create objects
var commLayerMock = new Mock<ICommLayer>();
var commHandler = new CommHandler(commLayerMock.Object);

// subscribe to CommHandler event
bool raised = false;
commHandler.OnCommHandlerEvent += delegate { raised = true; };

// Raise CommLayer event, ensure CommHandler event was subsequently raised
commLayerMock.Raise(m => m.OnCommLayerEvent += null, new CommLayerEventArgs());
Assert.True(raised);

You'll probably want to do something like this at every level, so that you know that if the interactions between each level work properly, the entire chain will work properly.

like image 43
ceyko Avatar answered Aug 25 '26 08:08

ceyko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!