This is the situation. I had async call so I needed to make Mid tier for this in order to be able to test it.
request.BeginGetResponse(new AsyncCallback(LoginCallback), requestState);
So, in order to be able to test this without real request, I created interface which I can mock.
public interface IRequestSender
{
void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState);
}
Then in implementation I can use call like that one above and I can provide some mock class to call my callback method regardless request is valid or not. My mock class looks like this.
public class RequestSenderMock : IRequestSender
{
public void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState)
{
var result = new Mock<IAsyncResult>();
result.Setup(x => x.AsyncState).Returns(requestState);
internalCallback(result.Object);
}
}
I can now easily create mock object in my unit test and use it. But when I create
var sender = new Mock<RequestSenderMock>();
I'm unable to verify call count for this object.
sender.Verify(x => x.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()), Times.Once());
It says that my method needs to be virtual. Is there a way to do this without making my method virtual? It would be best if I could somehow specify method impelementation when using interface.
var sender = new Mock<IRequestSender>();
And that somehow with Setup method or some other to make implementation on this mock object. Than I'll simply remove my mock class. Is this possible? What do you suggest?
I find it confusing that you are creating a manual mock and using a mocking-framework to mock it (mocking a mock). I would consider moving your custom functions into some utility class and using callbacks instead.
Example:
public class RequestSenderHelpers
{
public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState)
{
var result = new Mock<IAsyncResult>();
result.Setup(x => x.AsyncState).Returns(requestState);
internalCallback(result.Object);
}
}
[Test]
public void Callback_VerifyingWithMethodImplementation_VerifyWorks()
{
// arrange
var sender = new Mock<IRequestSender>();
sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(RequestSenderHelpers.Send);
// act
sender.Object.Send(null, delegate {}, null);
// assert
sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()));
}
To avoid the verbose setup you can wrap the setup of the method in an extension method and change your test accordingly:
public static class RequestSenderHelpers
{
public static void Send(HttpWebRequest request, AsyncCallback internalCallback, object requestState)
{
var result = new Mock<IAsyncResult>();
result.Setup(x => x.AsyncState).Returns(requestState);
internalCallback(result.Object);
}
public static void SetupSendWithMockedAsyncResult(this Mock<IRequestSender> sender)
{
sender.Setup(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>())).Callback<HttpWebRequest, AsyncCallback, object>(Send);
}
}
[Test]
public void Callback_VerifyingWithMethodImplementation_VerifyWorks()
{
// arrange
var sender = new Mock<IRequestSender>();
sender.SetupSendWithMockedAsyncResult();
// act
sender.Object.Send(null, delegate {}, null);
// assert
sender.Verify(s => s.Send(It.IsAny<HttpWebRequest>(), It.IsAny<AsyncCallback>(), It.IsAny<object>()));
}
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