Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock interface ReturnsAsync returning null

I am attempting to Mock an Interface that has a single Task<string> method.

The same Q here, though i can't seem to get the code to work in my favor: Setup async Task callback in Moq Framework

My interface looks like this:

public interface IHttpClient
{
    Task<string> GetStringAsync(string uri);
}

I am trying to mock this up as so:

var mockHttp = new Mock<IHttpClient>();
mockHttp.Setup(m => m.GetStringAsync("aPretendUrl")).ReturnsAsync("Some sort of string");

I am finding that the result of the GetStringAsync is null

In the controller, where this instance is injected, I am calling it as so:

string responseData = await _client.GetStringAsync(url);

Also trying

string responseData = _client.GetStringAsync(url).Result;

responseData is null in all cases.

I am sure I am missing something simple. Still new with Unit tests

Can anybody point out where I am going wrong?

Update

The full unit test looks like this:

[Test]
public void Given_EController_Called_With_unknown_pedi_Returns_NotFound()
{
    // Arrange
    AppSettings settings = new AppSettings()
    {
        DataWarehouseAPI = "http://myurl.com"
    };
    Mock<IOptionsSnapshot<AppSettings>> mockSettings = new Mock<IOptionsSnapshot<AppSettings>>();
    mockSettings.Setup(m => m.Value).Returns(settings);

    var mockHttp = new Mock<IHttpClient>();
    mockHttp.Setup(m => m.GetStringAsync("aPretendUrl")).ReturnsAsync("[]");

    EntryController controller = new EntryController(mockHttp.Object, mockSettings.Object);

     // Act
    IActionResult actionResult = controller.GetByPedimento("nothing").Result;

    // Assert
    Assert.IsAssignableFrom<NotFoundObjectResult>(actionResult);
    }
like image 740
Darren Wainwright Avatar asked Mar 08 '23 16:03

Darren Wainwright


1 Answers

If you don't care about the 'url' in the test then you may use:

It.IsAny<string>()

result:

mockHttp.Setup(m => m.GetStringAsync(It.IsAny<string>()))
    .ReturnsAsync("Some sort of string");

If you specify 'uri' parameter in setup then you have to match it in your test to get desired return value "Some sort of string" from the method. You can specify different results for different inputs:

[TestMethod]
public async Task GetStringAsync_moqSetup()
{
    var mockHttp = new Mock<IHttpClient>();

    mockHttp.Setup(m => m.GetStringAsync(It.IsAny<string>()))
        .ReturnsAsync("Other sort of string");
    mockHttp.Setup(m => m.GetStringAsync("first"))
        .ReturnsAsync("First sort of string");

     var firstTarget = await mockHttp.Object.GetStringAsync("first");
     var differentTarget = await mockHttp.Object
         .GetStringAsync("something completely different");

    Assert.AreEqual("First sort of string", firstTarget);
    Assert.AreEqual("Other sort of string", differentTarget);
}

Review the Quickstart of the framework in order to get a better understanding of how to use it.

like image 142
rudolf_franek Avatar answered May 07 '23 07:05

rudolf_franek