Not sure how I can fix this, trying to do a unit test on the method \"GetByTitle\"
Here are my definitions:
public class ArticleDAO : GenericNHibern
Here's how I Mock HttpMessageHandler:
private HttpRequestMessage requestMessage = new HttpRequestMessage();
Mock<HttpMessageHandler> handlerMock =
GetHttpMessageHandlerMock(HttpStatusCode.OK);
MyRestService myRestService = new MyRestService();
myRestService.client = new HttpClient(handlerMock.Object);
var response = myRestService.Get("");
//At this point, the Mock of HttpRequestMessage is called and the Callback fills my class variable requestMessage. I can now look inside the requestMessage.
var headers = requestMessage?.Headers.ToString();
var queryBegin = requestMessage.RequestUri.OriginalString.IndexOf('?');
var queryString = requestMessage.RequestUri.OriginalString.Substring(queryBegin + 1);
Assert.That(headers.Contains("x-api-key: fakeApiKey"));
//Helper methods below
private Mock<HttpMessageHandler> GetHttpMessageHandlerMock(HttpStatusCode statusCode)
{
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>()
, ItExpr.IsAny<CancellationToken>()
)
.Returns(Task.FromResult(GetFakeResponse(statusCode)))
.Callback<HttpRequestMessage, CancellationToken>((p, q) => requestMessage = p)
.Verifiable();
return handlerMock;
}
private HttpResponseMessage GetFakeResponse(HttpStatusCode statusCode)
{
var s = "{\"data\":{\"status\":\"SUCCESS\",\"errorCode\":\"\",\"errorMessage\":\"9\"}}";
HttpResponseMessage response = new HttpResponseMessage()
{
StatusCode = statusCode,
Content = new StringContent(s),
ReasonPhrase = "OK",
RequestMessage = new HttpRequestMessage()
};
return response;
}
I use this for almost all my REST tests, because I can pass in status, content, etc. So, I can test different return values.
In order to control the behavior of a mock object (in Moq, at least), you either need to mock an interface, or make sure that the behavior you're trying to control is marked virtual. In your comment, I understand it so that the instantiating of _mockArticleDao
is done something like this:
_mockArticleDao = new Mock<ArticleDAO>();
If you want to keep it as so, you need to mark the GetArticle
method virtual
:
public class ArticleDAO : GenericNHibernateDAO(IArticle, int>, IArticleDAO
{
public virtual IArticle GetByTitle(string title)
{
// ...
}
}
Otherwise (and this is what I recommend), mock the interface instead.
_mockArticleDao = new Mock<IArticleDAO>();
I had the same issue trying to mock a class I have no control over, from a framework. In my specific case I had to mock an HttpResponseMessage setting up the status code to return Ok, but how to do it if that property is not virtual?
This code does not work because StatusCode is not virtual:
var httpResponseMessage = new Mock<HttpResponseMessage>();
httpResponseMessage.SetupGet(x => x.StatusCode).Returns(HttpStatusCode.OK);
Answer:
Done. Now you can mock a derived object that can be used anywhere the original one is used, because it inherits from it. Here is the code for my MockableHttpResponseMessage class:
public class MockableHttpResponseMessage: HttpResponseMessage
{
public MockableHttpResponseMessage() : base() {}
public MockableHttpResponseMessage(HttpStatusCode code) : base (code) { }
public new virtual HttpStatusCode StatusCode {
get { return base.StatusCode; }
set { base.StatusCode = value; }
}
}
Now, this code works:
var httpResponseMessage = new Mock<MockableHttpResponseMessage>();
httpResponseMessage.SetupGet(x => x.StatusCode).Returns(HttpStatusCode.OK);