我试图在从实体框架返回数据的简单控制器上运行集成测试。我已经编写了单元测试,并且所有工作都按预期进行。
我已经连接了xUnit Integration测试,但是当我运行一个简单的Get to my controller时,却找不到404。如果我在浏览器中启动该项目并通过邮递员运行get命令,则会命中控制器并正确执行操作。
我的xUnit TestFixture类
public sealed class TestFixture<TStartup> : IDisposable where TStartup : class
{
public readonly TestServer Server;
public readonly HttpClient Client;
public TestFixture()
{
var builder = BuildWebHost();
Server = new TestServer(builder);
Client = Server.CreateClient();
}
public static IWebHostBuilder BuildWebHost()
{
var host = new WebHostBuilder()
.UseStartup<TestStartup>()
.ConfigureAppConfiguration((hostContext, config) =>
{
config.Sources.Clear();
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddJsonFile("appsettings.test.json", optional: true, reloadOnChange: true);
});
return host;
}
}
我的控制器测试班
public class FlowApiControllerTests : IClassFixture<TestFixture<Startup>>
{
private readonly HttpClient _httpClient;
public FlowApiControllerTests(TestFixture<Startup> fixture)
{
_httpClient = fixture.Client;
}
[Fact]
public async Task Get_FlowApiTest()
{
var response = await _httpClient.GetAsync("/flowapi");
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
var model = JsonConvert.DeserializeObject<List<FlowApi>>(content);
model.Count.Should().Be(2);
}
}
最后是我的控制器
[Route("[controller]")]
[ApiController]
public class FlowApiController : ControllerBase
{
private readonly IFlowApiRepository _repository;
public FlowApiController(IFlowApiRepository repository)
{
_repository = repository;
}
// GET: api/FlowApi
[HttpGet]
public async Task<IActionResult> Get()
{
var result = await _repository.Select<FlowApi>();
return Ok(result);
}
}
我不知道为什么我在测试中没有击中控制器,但可以从邮递员中击中它。
答案 0 :(得分:2)
由于@Ajeet Kumar向我指出了WebApplicationFactory的方向,因此我采用了the ASP.NET Core Integration Test docs中的方法,并修改了TestFixture类以反映该方法。我还导入了nuget包Microsoft.AspNetCore.Mvc.Testing。我的TestFixture类现在看起来像
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<ApiContext>));
if (descriptor != null)
{
services.Remove(descriptor);
}
// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<ApiContext>((options, context) =>
{
context.UseInMemoryDatabase("InMemoryDbForTesting");
});
services.AddTransient<DatabaseSeeder>();
// Build the service provider.
var sp = services.BuildServiceProvider();
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var db = scopedServices.GetRequiredService<ApiContext>();
// Ensure the database is created.
db.Database.EnsureCreated();
try
{
// Seed the database with test data.
var seeder = scopedServices.GetService<DatabaseSeeder>();
seeder.SeedFlowApplicationData().Wait();