public class TestStartup : Startup
{
private readonly Mock<ICarService> _carServiceMock;
public TestStartup(IConfiguration configuration) : base(configuration)
{
_carServiceMock = new Mock<ICarService>();
}
public override void ConfigureMyServices(IServiceCollection services)
{
services.AddSingleton(_carServiceMock.Object);
}
public override void ConfigureDatabase(IServiceCollection services)
{
services.AddDbContext<CarContext>(options => options.UseInMemoryDatabase("CarDb"));
services.AddTransient<DataSeed>();
}
}
public class TestFixture: IDisposable, ICollectionFixture<TestFixture>
{
public TestFixture()
{
_server = new TestServer(new WebHostBuilder()
.UseStartup<TestStartup>()
.UseEnvironment("Development"));
_client = _server.CreateClient();
}
}
内部控制器中我正在使用ICarService
,后者正在使用CarContext
从Db中检索数据。
public class CarController
{
private readonly ICarService _carService;
public CarController(ICarService carService)
{
_carService = carService;
}
[HttpGet]
public async Task<IActionResult> Get([FromRoute] int id)
{
var contact = await _carService.GetAsync(id); **// this is always null**
}
}
我的问题是:由于这是一个集成测试,因此我首先需要模拟ICarService吗?如果是,那么我在这里做错了什么?
如果您正在测试CarService
类与数据库的交互方式,那么您不应该在模拟它。
您要做的是使用真实的CarService
实现,并让依赖项注入将InMemoryDatabase作为CarContext
参数添加到该类中。
因此,删除Mock<ICarService>
并注册真实的。
为什么返回null?
在您的示例中,当您调用方法_carService.GetAsync(id)'
时,它正在调用模拟类。但是您尚未在模拟程序中使用Setup
任何方法,因此任何调用都将返回null
。
您需要添加以下内容,以使模拟方法返回值:
_carService.Setup(cs => cs.GetAsync(It.IsAny<int>()).Returns(1);
但是当您对CarService
使用模拟时,这不会调用内存数据库。