FakeItEasy Setup object is not returning in test method

1.2k Views Asked by At

I am testing a method with FakeItEasy fake object. Fake object is a MemoryStream.

[TestFixture]
public class ServerClientTests
{
    private IWebClient webClient;
    private ServerClient serverClient;

    [SetUp]
    public void Setup()
    {
        webClient = A.Fake<IWebClient>();
        serverClient = new ServerClient(webClient);

        var responseStreamBytes = Encoding.Default.GetBytes("OK");
        var responseStream = new MemoryStream();
        responseStream.Write(responseStreamBytes, 0, responseStreamBytes.Length);
        responseStream.Seek(0, SeekOrigin.Begin);

        var response = A.Fake<WebResponse>();
        A.CallTo(() => response.GetResponseStream()).Returns(responseStream);

        var request = A.Fake<WebRequest>();
        A.CallTo(() => request.GetResponse()).Returns(response);

        A.CallTo(() => webClient.GetRequest("http://localhost:8080/myserver")).Returns(request);

    }

        [Test]
        public void Test1()
        {
            var result = serverClient.GetRequest("http://localhost/myserver");

            Assert.AreEqual(2, result.Length);
      }
  }

And this is code under the test:

public interface IWebClient
{
    WebRequest GetRequest(string url);
}

public class ServerClient
{
    private readonly IWebClient client;

    public ServerClient(IWebClient client)
    {
        this.client = client;
    }

    public Stream GetRequest(string url)
    {
        return client.GetRequest(url).GetResponse().GetResponseStream();
    }
}

When I run test, it gives test exception => Expected: 2 But was: 0

I put break point in setup method and debug test. I see that Fake request GetResponse() method returns response with stream. That Length is 2.

But in test method, stream Length is 0.

Is there any settings about FakeItEasy? Or Where am I wrong?

1

There are 1 best solutions below

2
On BEST ANSWER

You're setting up

 A.CallTo(() => webClient.GetRequest("http://localhost:8080/myserver"))
                         .Returns(request);

but then calling

serverClient.GetRequest("http://localhost/myserver");

So, the webClient.GetRequest is passed "http://localhost/myserver", which doesn't match its expectation ("http://localhost8080/myserver"), so the webClient returns a fake MemoryStream of its own devising, with default behaviour.

You may want to make the two URLs the same. Or if you want to have your fake webClient be responsive to more than just the one URL, you could use more sophisticated argument matchers.

In the future, if this sort of confusion arises over why a configured method doesn't behave the way you want, you could consider temporarily using a call to MustHaveHappened to check whether FakeItEasy thinks the method was called. We like to think FakeItEasy's error messages are pretty good at helping in this situation.

In your case, if you'd added a test like

[Test]
public void Test2()
{
    var result = serverClient.GetRequest("http://localhost/myserver");

    A.CallTo(() => webClient.GetRequest("http://localhost:8080/myserver"))
        .MustHaveHappened();
}

It would've said

Assertion failed for the following call:
  FakeItEasyQuestions.IWebClient.GetRequest("http://localhost:8080/myserver")
Expected to find it at least once but found it #0 times among the calls:
  1: FakeItEasyQuestions.IWebClient.GetRequest(url: "http://localhost/myserver")