zlZimon
zlZimon

Reputation: 2489

How to unit test a method with a nested action / callback

I want to test a method which sends out a Webrequest and receives the response. However this does not happen directly, instead it uses another class which builds the request and sends it. Furthermore the HttpRequest class uses a callback for the response which was passed from the "building class", which got it from the method I want to test.

Some code will make it clearer. (simplified)

// this is the actual method I want to unit test
public void GetSomeDataFromTheWeb(Action<ResponseData> action, string data)
{
    _webService.GetSomeDataFromTheWeb((req, resp) =>
    {
        // building the response depending on the HttpStatus etc
        action(new ResponseData());
    },data);
}

// this is the "builder method" from the _webService which I am gonna mock in my test
  public void GetSomeDataFromTheWeb(Action<HTTPRequest, HTTPResponse> response, string data)
{
    HTTPRequest request = new HTTPRequest(new Uri(someUrl)), HTTPMethods.Get,
        (req, resp) =>
        {
            response(req, resp);
        });            
    request.Send();
}

I can create a HttpResponse the way it should look like, but I have no idea how to get this "into" the response(req,resp) call of the last method.

How can I mock the _webService that it calls the correct callback from the method I want to test with the HttpResponse I am gonna feed into my unit test?

Basically something like this:

[Fact]
public void WebRequestTest()
{
  var httpresponse = ResponseContainer.GetWebRequestResponse();
  var webserviceMock = new Mock<IWebService>();

  //get the response somehow into the mock
  webserviceMock.Setup(w=>w.GetSomeDataFromTheWeb( /*no idea how*/));

  var sut = new MyClassIWantToTest(webserviceMock);

  ResponseData theResult = new ResponseData();
  sut.GetSomeDataFromTheWeb(r=>{theResult = r}, "");

  Assert.Equal(theResult, ResultContainer.WebRequest());
}

Upvotes: 2

Views: 1358

Answers (1)

Nkosi
Nkosi

Reputation: 247123

Setup the GetSomeDataFromTheWeb with It.IsAny arguments and use the Callback on the Setup to grab the action and call it with your stubs.

https://github.com/Moq/moq4/wiki/Quickstart#callbacks

webserviceMock
    .Setup(w=>w.GetSomeDataFromTheWeb( It.IsAny<Action<HTTPRequest, HTTPResponse>>, It.IsAny<string>))
    .Callback((Action<HTTPRequest, HTTPResponse> response, string data)=>{...});

Upvotes: 1

Related Questions