I've just started to implement unit tests (using xUnit and Moq) on an already established project of mine. The project extensively uses dependency injection via the unity container.
I have two services A and B. Service A is the one being tested in this case. Service A calls B and gives it a delegate to an internal function. This 'callback' is used to notify A when a message has been received that it must handle.
Hence A calls (where b is an instance of service B):
b.RegisterHandler(Guid id, Action<byte[]> messageHandler);
In order to test service A, I need to be able to call messageHandler
, as this is the only way it currently accepts messages.
Can this be done using Moq? ie. Can I mock service B, such that when RegisterHandler
is called, the value of messageHandler
is passed out to my test?
Or do I need to redesign this? Are there any design patterns I should be using in this case? Does anyone know of any good resources on this kind of design?
You can get an instance of the callback (or any other input parameter) by using the Callback (the name similarity is incidental) method on the Mock:
[TestMethod]
public void Test19()
{
Action<byte[]> callback = null;
var bSpy = new Mock<IServiceB>();
bSpy.Setup(b => b.RegisterHandler(It.IsAny<Guid>(), It.IsAny<Action<byte[]>>()))
.Callback((Guid g, Action<byte[]> a) => callback = a);
var sut = new ServiceA(bSpy.Object);
sut.RegisterCallback();
Assert.AreEqual(sut.Do, callback);
}
This works when ServiceA is defined as this:
public class ServiceA
{
private readonly IServiceB b;
public ServiceA(IServiceB b)
{
if (b == null)
{
throw new ArgumentNullException("b");
}
this.b = b;
}
public void RegisterCallback()
{
this.b.RegisterHandler(Guid.NewGuid(), this.Do);
}
public void Do(byte[] bytes)
{
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With