hibri / HttpMock

A library for creating Http servers on the fly in tests and stubbing responses
MIT License
128 stars 44 forks source link

Request handler invokes 2 times #91

Open kos811 opened 6 years ago

kos811 commented 6 years ago

Hi!

When i tried to use this library, i found some intresting issue: when i call a handler, it invokes twice. This problem reproduces when i make a call with Fiddler, Postman or by Opera browser.

Sources of test:


using System;
using System.Threading;
using HttpMock;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var delaySeconds = TimeSpan.FromSeconds(2);
            var serverAddr = "http://localhost:9191";
            var apiPath = "/profileImporter/invoke";
            var url = serverAddr + apiPath;
            Console.WriteLine($"{nameof(url)} : {url}");

            var mockApi = HttpMockRepository.At(serverAddr);
            mockApi.Stub(x => x.Get("")).Return(() =>
            {
                Console.WriteLine($"{DateTime.Now:yyyyMMdd HH:mm:ss} - server called");
                Console.WriteLine($"Delay: {delaySeconds}");
                Thread.Sleep(delaySeconds);
                Console.WriteLine($"{DateTime.Now:yyyyMMdd HH:mm:ss} - delay ended");
                Console.WriteLine();
                Console.WriteLine();
                return "TEST_GET_RESULT";
            }).OK();

            Console.WriteLine("Press any key to exit this shit...");
            Console.ReadKey();
        }

    }
}

image

hibri commented 6 years ago

Hi @kos811 , Thanks for reporting this. I haven't seen this issue before. Will have a look. There is a test that checks for multiple invocations, and I haven't seen it fail yet. https://github.com/hibri/HttpMock/blob/master/src/HttpMock.Integration.Tests/HttpExpectationTests.cs#L147

DavidSSL commented 6 years ago

Hi,

I've reproduced the problem as outlined by the original poster and using a modified version of the test you've referenced: ` [Test] public void Should_match_many_POST_requests_which_were_made_with_expected_body()

    {
        var _hostUrl = "http://localhost:9192";
        var stubHttp = HttpMockRepository.At(_hostUrl);

        stubHttp.Stub(x => x.Post("/endpoint/handler")).Return(() =>
        {
            counter++;
            return "OK";
        }).OK();

        const string expectedData = "postdata";

        new WebClient().UploadString($"{_hostUrl}/endpoint/handler", expectedData);

        new WebClient().UploadString($"{_hostUrl}/endpoint/handler", expectedData);

        stubHttp.AssertWasCalled(x => x.Post("/endpoint/handler")).Times(2);

        Assert.That(counter, Is.EqualTo(2));

    }`
bacon1986 commented 6 years ago

This is due to it calling the Func once to get the length of the body when it prepares the headers and then again to get the actual body of the response.

Merx commented 4 years ago

Hi, I still have the same issue that it is called twice when calling request.GetResponse(); just once.

Merx commented 4 years ago

Here is the mini version of our test to reproduce the problem (using HttpMock v2.3.1):

    [TestMethod]
    public void TestIfCalledMultipleTimes()
    {
        string serverAddress = "http://localhost:9195";
        string endpoint = "/someEndpoint";
        int callCounter = 0;

        // Setup http mock
        var httpMock = HttpMockRepository.At($"{serverAddress}");
        httpMock.Stub(x => x.Get($"{endpoint}")).Return(
            () => {
                Console.WriteLine($"Call number {++callCounter}");
                return "true";
            })
            .OK();
        while (!httpMock.IsAvailable()) { Thread.Sleep(50); }

        // Call http mock
        var request = WebRequest.Create($"{serverAddress}{endpoint}");
        request.ContentLength = 0;
        request.Method = "GET";
        Console.WriteLine($"Calling {serverAddress}{endpoint}");
        var response = request.GetResponse();

        // Check call counter
        Thread.Sleep(50);
        callCounter.Should().Be(1);
    }

and here is the according test output

    Expected callCounter to be 1, but found 2.
        <some exception stack trace>
    Calling http://localhost:9195/someEndpoint
    Call number 1
    Call number 2
hibri commented 4 years ago

Thanks @Merx Re-opened this.