How should I test an EF core repository with xunit

Asked

Viewed 95 times

1

I’m currently testing a repository as follows:

public class SomethingTest
{
    [Fact]
    public async void GetKeyValuesAsync_NotNull()
    {

        // Arrange
        var categoryRepository = CreateRepository();
        var fixture = new Fixture().Customize(new AutoMoqCustomization());
        var categoryModel = fixture.Build<Category>()
                        .Without(x => x.Property)
                        .Create();

        // Act
        var categoryCreated = await categoryRepository.CreateAsync(categoryModel);
        var result = await categoryRepository.GetKeyValuesAsync();

        //Assert
        Assert.NotNull(result);
    }

    private CategoryRepository CreateRepository()
    {
        var services = new ServiceCollection();
        services.AddDbContext<TokensContext>(x => { x.UseInMemoryDatabase(databaseName: "StoreMemoryContext", new InMemoryDatabaseRoot()); });
        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        var serviceProvider = services.BuildServiceProvider();
        var mockLocalizationService = new Mock<ILocalizationService>();
        var mockNormalizationService = new Mock<INormalizationService>();
        var mockLogger = new Mock<ILogger<CategoryRepository>>();
        return new CategoryRepository(serviceProvider,
                                    mockLocalizationService.Object,
                                    mockNormalizationService.Object,
                                    mockLogger.Object);


    }
}

I believe that the way I am from the sql Provider to Useinmemorydatabase is not the most correct, but I do not know how I can change otherwise

What seems to be happening is that I am there creating a mock of the Iserviceprovider but internally the EF is using another Iserviceprovider with you uses only one knowing that I have to pass it in the constructor of the class Categoryrepository the parameter Iserviceprovider ?

Error generated for Warning 'Microsoft.EntityFrameworkCore.Infrastructure.Manyservicepiderscreatedwarning': More than twenty 'Iserviceprovider' instances have been created for Internal use by Entity Framework. This is commonly caused by Injection of a new Singleton service instance into Every Dbcontext instance. For example, Calling Useloggerfactory Passing in a new instance each time-see https://go.microsoft.com/fwlink/? linkid=869049 for more Details. Consider reviewing calls on 'Dbcontextoptionsbuilder' that may require new service providers to be built. This Exception can be suppressed or logged by Passing Event ID 'Coreeventid.Manyserviceproviderscreatedwarning' to the 'Configurewarnings' method in 'Dbcontext.Onconfiguring' or 'Adddbcontext'.

  • "Useinmemorydatabase is not the correct Useinmemorydatabase" this is the simplest way to solve this and is widely used, but perhaps the best would be to separate the EF from the implementation, so in a Repository for example, then it would be easy to inject a Repository mock for the tests :) If the project is early it would be great to separate the dependency with a Repository

  • @Ricardopunctual actually this separate class Categoryrepository is where has the implementation

  • then neither need to mock the Dbcontext but the Categoryrepository method makes a var mockRepo = new Mock<ICategoryRepository>() and then mockRepo.Setup(s => s.NomeMetodo...).Returns(categoryModel). Now if you want to test the Repository there is no way, better use a inMemory

  • I think what is happening there is that I am there creating a mock of the Iserviceprovider but internally the EF is using another Iserviceprovider with you uses only one knowing that I have to pass it in the constructor of the class Categoryrepository?

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.