0
votes

I have those two methods, SendMessage is a recursive and non-overridable and SendMessageUsingHttpClient is virtual so I can mock any return on my test class.

public HttpResponseMessage SendMessage(HttpRequestMessage httpRequestMessage, HttpStatusCode? httpStatusCode = null)
{
    // not relevant
    GetRandomTokenAndAddInMessageHeader(httpRequestMessage, httpStatusCode);

    var response = SendMessageUsingHttpClient(httpRequestMessage);

    if (response.StatusCode == HttpStatusCode.Unauthorized)
        SendMessage(httpRequestMessage, HttpStatusCode.Unauthorized);

    return response;
}

public virtual HttpResponseMessage SendMessageUsingHttpClient(HttpRequestMessage httpRequestMessage)
{
    return _httpClient.Send(httpRequestMessage, CancellationToken.None);
}

I need to test this line if (response.StatusCode == HttpStatusCode.Unauthorized), so here's my test method:

[TestMethod]
public void Send_MustReturn_UnauthorizedMock_Then_OkMock()
{
    var mockHttpResponseManager = new Mock<HttpRequestManager>();

    var expectedUnauthorizedResponse = new HttpResponseMessage { StatusCode = HttpStatusCode.Unauthorized };
    var expectedOkResponse = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };

    mockHttpResponseManager.SetupSequence(m => m.SendMessageUsingHttpClient(It.IsAny<HttpRequestMessage>()))
        .Returns(expectedUnauthorizedResponse)
        .Returns(expectedOkResponse);

    mockHttpResponseManager.Object.SendMessage(new HttpRequestMessage());

    mockHttpResponseManager.Verify(v => v.SendMessage(It.IsAny<HttpRequestMessage>(), It.IsAny<HttpStatusCode?>()), Times.Exactly(2));
}

If I run this test, as SendMessage isn't virtual, it'll throw the following exception:

Unsupported expression: v => v.SendMessage(It.IsAny<HttpRequestMessage>(), It.IsAny<HttpStatusCode?>())

Non-overridable members (here: HttpRequestManager.SendMessage) may not be used in setup / verification expressions.

And if I make SendMessage virtual, Moq won't count the second (recursive) call, only the one that Moq itself called inside my test class.

Expected invocation on the mock exactly 2 times, but was 1 times: 

v => v.SendMessage(It.IsAny<HttpRequestMessage>(), It.IsAny<HttpStatusCode?>())
    
Performed invocations:
    
Mock<HttpRequestManager:1> (v): 

HttpRequestManager.SendMessage(Method: GET, RequestUri: '<null>', Version: 1.1, Content: <null>, Headers: {}, null)

Thank you!