Search code examples
c#exceptiondisposedotnet-httpclientshim

ShimNotImplementedException : System.Net.Http.HttpMessageInvoker.Dispose()


I am using a shim (generated by Visual Studio) to fake an HttpClient instance. Below is SUT:

public class ExampleForSO
{

    private HttpClient _httpClient;

    public ExampleForSO(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<List<string>> GetListAsync()
    {
        using (_httpClient)
        {
            return await GetListFromHostAsync(_httpClient);
        }
    }

    public async Task<List<string>> GetListFromHostAsync(HttpClient httpClient)
    {

        var responseJson = await
            httpClient.GetAsync("abc")
            .Result.Content.ReadAsStringAsync()
            ;

        var fList = JsonConvert.DeserializeObject<List<string>>(responseJson);

        return fList;
    }

Here is the unit test:

[TestMethod]
public void TestMethod1()
{
    // Create a fake HttpClient
    using (ShimsContext.Create())
    {
        var fake = new ShimHttpClient()
        {

            GetAsyncString = (uri) =>
            {
                var hrm = new HttpResponseMessage(HttpStatusCode.OK);
                var list = new List<string>() {"file1", "file2"};
                hrm.Content = new StringContent(JsonConvert.SerializeObject(list));
                var t = new Task<HttpResponseMessage>(() => hrm);
                return Task.Run(() => hrm);
            }

        };

        var _exampleForSO = new ExampleForSO(fake);

        var returnValue = _exampleForSO.GetListAsync();

        // This line will throw an exception:
        var value = returnValue.Result;

        Assert.IsNotNull(returnValue);

    }
}

When I run this the shim throws a ShimNotImplemented exception. The stack trace shows this:

$Action1NotImplemented71f6f23c-d227-4cb6-ac76-1f8c8094c413.Invoke(HttpMessageInvoker arg1) at System.Net.Http.HttpMessageInvoker.Dispose()

If I comment out the line using (_httpClient), the unit test will run without throwing the exception, but that is not a good solution for production. My question, how can I assign a function to the System.Net.Http.HttpMessageInvoker.Dispose() shim delegate? I am not able to find a reference to it anywhere. Do I have to create a fake for the HttpMessageInvoker to and assign to another shim property?


Solution

  • did you try this: Visual Studio 2013 Update 4 Changes MSFakes Shim Object Default Behaviour basically, call Microsoft.QualityTools.Testing.Fakes.Shims.ShimBehaviors.BehaveAsDefaultValue(); before instantiating the shim