4

The problem I try to solve:

How to test client code that calls REST together with real REST server code (in an efficient way)?

Goals:

  1. It would be kind of integration test, but fast and easy

  2. It would allow to detect e. g. bug where client calls REST method with wrong verb (e. g. PUT, but API accepts POST)

  3. I find it overcomplicated to make integration tests with deployment of REST service and then using my API library to call, so I think of replacing it with in-memory unit/integration tests

  4. I find Flurl library useful, so I would like to use it in such test.

  5. Inspiration: https://stackoverflow.com/a/37510032/1453525

My idea: I would like to make my Flurl Api tests against real ApiController running in memory (using HttpServer), not using Flurl HttpTest. I found this technique here: https://stackoverflow.com/a/37510032/1453525 However it requires to build HttpRequest message each time and does not have nice Api for testing. Is it possible to run Flurl code against real in-memory ApiController tests?

1
  • Internally Flurl is using HttpClient so you can still configure it to use one that was generated by in-memory HttpServer Commented Jul 17, 2017 at 10:46

1 Answer 1

3

I have not tested this, but I believe you should be able to use Flurl with in-memory hosting by creating a custom HttpClientFactory and overriding CreateMessageHandler:

public class TestingClientFactory : DefaultHttpClientFactory
{
    public overrride HttpMessageHandler CreateMessageHandler()
    {
        var config = new HttpConfiguration();
        //configure web api
        WebApiConfig.Register(config);

        return new HttpServer(config);
    }
}

In your test assembly, register this globally, ideally running just once on test fixture setup:

FlurlHttp.Configure(settings => settings.HttpClientFactory = new TestingClientFactory());

Now every time Flurl needs to create a new HttpClient in your tests, it will use the in-memory server.

Sign up to request clarification or add additional context in comments.

6 Comments

Based on my review of the source repo this should work. Depending on where the controllers are defined they may need to call the WebApiConfig.Register from the Presentation layer and apply it to the config
@Todd Menier: I setup this code, however it is no difference than without TestingClientFactory. CreateMessageHandler() is not executed (not hit in debugger). I have no idea why. I use HttpTest().
@one_mile_run As I've said before, do not use HttpTest. That is specifically for faking all HTTP calls made with Flurl, which isn't what you want to do. You want to make real calls to your in-memory HttpServer. CreateMessageHandler isn't getting hit because the existence of HttpTest causes it to be bypassed.
@ToddMenier: Ok, I understand now why I should not use HttpTest. I assumed I would use its Assert API, but it makes no sense since calls are not faked. After couple tries I got final test working. I had to tweak TestingClientFactory to register my DI resolver and setup configuration values. Still, I am not sure if FlurlHttp.Configure() will be ok for parallel tests, because it seems to be a global configuration. Is this a design decision?
@one_mile_run FlurlHttp.Configure should be called once at app startup. For an NUnit test suite, do it here.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.