Git Product home page Git Product logo

Comments (14)

martincostello avatar martincostello commented on August 17, 2024 1

I like the idea of an optional “use this if nothing better” - it’s a use case I hadn’t really considered when coming up with the initial design.

I think something fairly “generic” that supports being asynchronous, for example if you want to read from a file to get the default body, should be good enough to accomplish your use case.

I’m keen to not have too much pattern matching etc. being built in, as that’s got the potential to lead to bloat trying to cater for all the things people might want to do in their test scenarios.

Instead, I think hooks like this allow enough extensibility to “bring your own implementation” without the library getting too opinionated.

Feel free to submit a PR!

from httpclient-interception.

stephenthrelfall avatar stephenthrelfall commented on August 17, 2024 1

It's also about clarity. I think this example using your library:

                // Setup an expected response
                var builder = new HttpRequestInterceptionBuilder()
                    .ForHttp()
                    .ForUri(connectionDetails.ConnectionUri)
                    .ForPath("orders")
                    .ForQuery($"id=12")
                    .WithStatus(HttpStatusCode.OK)
                    .WithContent(testJson);

Conveys it's intentions much more clearly than something like this:

            var messageHandler = new Mock<MockableMessageHandler>();
            var httpClient = new HttpClient(messageHandler.Object);

            messageHandler
                .Setup(m => m.DoSendAsync(It.IsAny<HttpRequestMessage>()))
                .ReturnsAsync(new HttpResponseMessage()
            {
                Content = new StringContent(testJson)
            });

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

I've just refreshed myself with the code, and it looks like part of what you want is already there, but not all of it.

We do have an OnSend property on HttpClientInterceptorOptions that you can use to inspect every request as they flow through:

https://github.com/justeat/httpclient-interception/blob/204e16d7a5733cff68274564a60424852c2f390d/src/HttpClientInterception/HttpClientInterceptorOptions.cs#L57-L60

But ultimately that still calls through into the code to find a matching response, which expects to find a registration, and if not, calls through to the inner handler (unless ThrowOnMissingRegistration is set to true), which means you still need to register something to match the request.

I guess what you're kind of after is a way to register a "catch-all" response for anything that doesn't match something more specific?

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

Something like this maybe?

var options = new HttpClientInterceptorOptions();

options.OnMissingRegistration = (request) =>
{
    return Task.FromResult(new HttpResponseMessage());
};

from httpclient-interception.

stephenthrelfall avatar stephenthrelfall commented on August 17, 2024

from httpclient-interception.

stephenthrelfall avatar stephenthrelfall commented on August 17, 2024

I had envisaged it working more like this:

var builder = new HttpRequestInterceptionBuilder()
                    .ForHttp()
                    .ForPath("orders")                    
                    .WithContent("{}");

Would match any request with "orders" as the path and any query string.

var builder = new HttpRequestInterceptionBuilder()
                    .ForHttp()
                    .ForPath("orders") 
                    .ForQuery($"id=12")                   
                    .WithContent("{}");

Would match any request with "orders" as the path and "id=12" as the query string.

Maybe that is what you were referring to when you said too much pattern matching? Maybe this could be a separate kind of builder?

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

The problem with that approach is that that would break the current behaviour, where an unspecified host implies localhost and no query string implies no query string at all.

Ignoring query strings from matching behaviour was added by #10. We could maybe add in an "any host" matching behaviour in the same vein?

However then I'd be worried that in tests for an application that had more than one external dependency that users could mistakenly miss issues where their tests were hitting the "wrong" host name and they wouldn't notice because it now wouldn't matter.

I wonder if there's a way we could combine the two approaches somehow? Have a general "catch all" hook to allow you to provide you the opportunity to provide an arbitrary response for an arbitrary request that hasn't matched already, but then have a simple builder available that you can use to build a response easily after the "bring-your-own" condition has been satisfied?

from httpclient-interception.

stephenthrelfall avatar stephenthrelfall commented on August 17, 2024

I think requiring users to specifically call the AnyHost() method to get that kind of behaviour would mitigate the risk of it being done mistakenly and is quite explicit in the test, which I definitely like.

Also, I think the main use case for this type of behaviour would be in unit testing so I think it's unlikely that the issue with multiple hosts could become a factor.

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

Would you be able to share a code example of roughly what you're trying to achieve in your specific user case?

I'm curious as to what the bigger picture is that's raising the need to use this library in-lieu of a simpler unit test of a HttpMessageHandler implementation coupled with a mocking framework.

That aside, I like the idea of something like AnyHost() being the way to enable the behaviour if we implemented it, though off the top of my head I'm not sure how we'd implement it under the hood as a lot of the current behaviour leverages off the back of UriBuilder.

from httpclient-interception.

stephenthrelfall avatar stephenthrelfall commented on August 17, 2024

I used the library to replace httpclient in my unit, integration and functional tests. I guess I favoured this approach over rolling my own as it provides a common language used throughout my tests for mocking the httpclient and it provides almost all the functionality I required already.

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

Right OK, so more for consistency of approach across your different levels of test?

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

I'll have a tinker around in a branch later this afternoon and see if some inspiration strikes.

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

Have raised a PR for further discussion and review based on the ideas here in #21.

from httpclient-interception.

martincostello avatar martincostello commented on August 17, 2024

Resolved by #21.

from httpclient-interception.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.