我有一个IntegrationTestHelper类,我用它来创建一个带有模拟InMemory数据库的WebApplicationFactory。
public class IntegrationTestHelper
{
public WebApplicationFactory<RentAPI.Program> GetWebApplicationFactory(string databaseName)
{
var factory = new WebApplicationFactory<RentAPI.Program>().WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
var dbContextDescriptor = services.SingleOrDefault(d =>
d.ServiceType == typeof(DbContextOptions<ApplicationDbContext>));
services.Remove(dbContextDescriptor);
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase(databaseName);
});
});
});
using var scope = factory.Services.CreateScope(); ;
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
SeedData(userManager, roleManager, db).Wait();
return factory;
}
...
}
字符串
我在下一个测试中使用GetWebApplicationFactory来获取WebApplicationFactory示例,然后再次使用WithWebHostBuilder来模拟IFilecommunication Service,但它不起作用。API继续使用Program.cs中添加的IFilecommunication Service的实现。
public class PropertyControllerTests
{
private IntegrationTestHelper _helper;
private WebApplicationFactory<RentAPI.Program> _factory;
private HttpClient _client;
[SetUp]
public void Setup()
{
_helper = new IntegrationTestHelper();
_factory = _helper.GetWebApplicationFactory(Guid.NewGuid().ToString());
}
#region AddNewProperty
[Test]
public async Task AddNewProperty_ReturnsOk()
{
// Arrange
_factory.WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
var fileStorageService = services.SingleOrDefault(d => d.ServiceType == typeof(IFileStorageService));
services.Remove(fileStorageService);
var mockedService = new Mock<IFileStorageService>();
mockedService.Setup(_ => _.UploadFilesAsync(It.IsAny<IFormFile[]>()))
.ReturnsAsync(new List<string> { "fileId1", "fileId2" });
services.AddScoped(_ => mockedService.Object);
});
});
_client = _factory.CreateClient();
... // creating and setting data in content
// Act
var response = await _client.PostAsync("property/landlord/add", content);
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}
[TearDown]
public void TearDown()
{
_client.Dispose();
_factory.Dispose();
}
}
型
但是当我搬家的时候
var fileStorageService = services.SingleOrDefault(d => d.ServiceType == typeof(IFileStorageService));
services.Remove(fileStorageService);
var mockedService = new Mock<IFileStorageService>();
mockedService.Setup(_ => _.UploadFilesAsync(It.IsAny<IFormFile[]>()))
.ReturnsAsync(new List<string> { "fileId1", "fileId2" });
services.AddScoped(_ => mockedService.Object);
型
到GetWebApplicationFactory,一切都开始工作了。
public WebApplicationFactory<RentAPI.Program> GetWebApplicationFactory(string databaseName)
{
var factory = new WebApplicationFactory<RentAPI.Program>().WithWebHostBuilder(builder =>
{
builder.ConfigureTestServices(services =>
{
var dbContextDescriptor = services.SingleOrDefault(d =>
d.ServiceType == typeof(DbContextOptions<ApplicationDbContext>));
services.Remove(dbContextDescriptor);
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase(databaseName);
});
var fileStorageService = services.SingleOrDefault(d => d.ServiceType == typeof(IFileStorageService));
services.Remove(fileStorageService);
var mockedService = new Mock<IFileStorageService>();
mockedService.Setup(_ => _.UploadFilesAsync(It.IsAny<IFormFile[]>()))
.ReturnsAsync(new List<string> { "fileId1", "fileId2" });
services.AddScoped(_ => mockedService.Object);
});
});
using var scope = factory.Services.CreateScope(); ;
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
SeedData(userManager, roleManager, db).Wait();
return factory;
}
型
它可以工作,但对我来说,这种实现并不方便。
那么,在创建WebApplicationFactory之后,是否可以模拟服务呢?
1条答案
按热度按时间j0pj023g1#
如果你检查
WithWebHostBuilderCore
,你会看到它返回你完全忽略的WebApplicationFactory<TEntryPoint>
。尝试使用它:字符串
至于“original”
_factory
-factory.Services
(为种子调用)将在内部初始化测试服务器,这需要从服务集合中构建服务提供者,从注册的Angular 来看,默认服务提供者基本上是只读的(即,您不能添加/删除注册)。