Search code examples
c#asp.net-coreintegration-testingxunit

Mock service for xUnit


I have an application that currently works as designed, but I am trying to setup integration testing with xUnit before I expand upon it. At the moment the test will only use the original service when performing the test and I don't see why.

This the is the test:

using IStoreRepository = Repositories.V3.Interfaces.IStoreRepository;

public class StoreTests : IClassFixture<WebApplicationFactory<Startup>> {
    private readonly ITestOutputHelper _output;
    private readonly WebApplicationFactory<Startup> _factory;
    private readonly string _url;

    public StoreTests(ITestOutputHelper output, WebApplicationFactory<Startup> factory) {
        _output = output;
        _factory = factory;

        _url = "/api/store";
    }

    [Theory]
    [InlineData("GET", "FAKE123")]
    public async Task StoreByCode(string method, string code = null) {
        // var client = _factory.CreateClient();

        var client = _factory.WithWebHostBuilder(builder => {
            builder.ConfigureTestServices(services => {
                services.AddScoped<IStoreRepository, StoreRepositoryTest>();
            });
        }).CreateClient();

        var request = new HttpRequestMessage(new HttpMethod(method), $"{_url}/{code}");

        string readAsStringAsync;

        _output.WriteLine($"Request Uri: {request.RequestUri}");

        using (var response = await client.SendAsync(request)) {
            response.EnsureSuccessStatusCode();
            readAsStringAsync = await response.Content.ReadAsStringAsync();

            if (!response.IsSuccessStatusCode) {
                _output.WriteLine($"Not successful ({response.StatusCode}): {readAsStringAsync}");
            }
        }

        var stores = JsonConvert.DeserializeObject<List<Store>>(readAsStringAsync);

        Assert.True(stores.Any());
    }
}

However when I conduct the test the break point in the real Repository, StoreRepository that is registered in Startup.cs is the one that is hit, not the break point in StoreRepositoryTest. I setup my factory to override the dependency, but it's ignoring it. What can I do to correct this.

For reference, I have been using this source: https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2

Update

Not sure if this question should be deleted or not but it ended up being a really silly mistake. I updated the code above to include a using alias. It turned out I was registering and overriding the V1 interface instead of V3. When I implemented the Mock class I didn't realize I was implementing the old service. So the good news is the above code is a working example of how to mock using Microsoft's documentation.


Solution

  • I have seen this before. You probably created an interface in a different namespace.

    Typically, this happens when you have a version 1 interface for a web service, and then you decide to add new functionality. You then create a version 2 interface with exactly the same name.

    Put a break point on services.AddScoped<IStoreRepository, StoreRepositoryTest>() and debug that. Inspect the results and scroll to the bottom where your services are being added; You’ll get a clear view of what’s being added.