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
– Ricardo Pontual
@Ricardopunctual actually this separate class Categoryrepository is where has the implementation
– Amadeu Antunes
then neither need to mock the Dbcontext but the Categoryrepository method makes a
var mockRepo = new Mock<ICategoryRepository>()
and thenmockRepo.Setup(s => s.NomeMetodo...).Returns(categoryModel)
. Now if you want to test the Repository there is no way, better use a inMemory– Ricardo Pontual
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?
– Amadeu Antunes