Closed niwrA closed 3 years ago
I'm not sure if this is exactly the problem you're describing, but it does seem that because the response helpers immediately create and pass an HttpResponseMessage to ReturnsAsync like this, each request gets the same response instance, which means if an app makes multiple requests against one setup and reads the response body each time, the HttpContent will have been disposed the second time around. Verified this problem with the following test:
[Fact]
public async Task MultipleRequestsCanBeMadeAgainstOneSetup()
{
var handler = new Mock<HttpMessageHandler>();
var client = handler.CreateClient();
handler.SetupRequest(HttpMethod.Get, "https://example.com/foo")
.ReturnsResponse("bar");
(await client.GetStringAsync("https://example.com/foo")).Should().Be("bar");
(await client.GetStringAsync("https://example.com/foo")).Should().Be("bar");
(await client.GetStringAsync("https://example.com/foo")).Should().Be("bar");
handler.VerifyRequest(HttpMethod.Get, "https://example.com/foo", Times.Exactly(3));
}
// System.ObjectDisposedException : Cannot access a disposed object.
// Object name: 'System.Net.Http.StringContent'.
I can fix this by creating the response in a .Returns(async (...) =>
callback so that each request gets its own HttpResponseMessage. (That would also allow me to populate response.RequestMessage
, in case anyone uses that.)
Is this the problem you were seeing, though? I wasn't able to reproduce a situation where subsequent calls don't get a response at all, so I'm wondering if maybe the disposed HttpContent is what's causing the issue you're seeing with the second call (perhaps something's catching that exception and making it look like it's not returning anything?).
I think it does fit our situation, though I can't tell for sure - we are mocking a call inside a third party component and do not get the inner exception here. I guess it wouldn't hurt to fix this anyway, and then I suspect our issue will be solved. It's not urgent because we have this workaround, but let me know when it is fixed and then I can test it.
Sorry for the wait! I published a new version; details of the change here in the PR. Let me know if this fixes the problem for you.
Hi,
Nice library! I am not a fan of extension methods but in this case didn't want to wrap the httpclient and factory stuff in an own interface, and this was a nice and quick solution.
We ran into one unexpected behaviour that seems inconsistent with Moq
Expected behavior:
Actual behavior:
Workaround:
(If I have time later I'd be willing to see if I could fix this myself with a unit test - looking at the tests helped me guess where the issue is, as I couldn't find a test setup for this scenario)