【发布时间】:2019-10-10 07:26:03
【问题描述】:
public Fixture()
{
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddScoped<ICarService, CarService>();
}));
Client = _server.CreateClient();
}
从测试中我使用这个HttpClient 来测试我的API。
using (var response = await _client.GetAsync($"/api/car/{id}"))
{
//...
}
问题是我想在CarService 类中伪造GetAsync(int id) 方法的结果。
所以我尝试了
var myCarObject = ... omitted for clarity
var myCarMockService = new Mock<ICarService>();
myCarMockService.Setup(x => x.GetAsync(It.IsAny<int>())).Returns(Task.FromResult(myCarObject));
我不知道这是正确的方法,但如果是我该如何注入它
进入Fixture 类,以便CarService 可以使用它。
public class CarService: ICarService {
private readonly CarDbContext _carDbContext;
public CarService(CarDbContext carDbContext)
{
_carDbContext = carDbContext;
}
public async Task<Car> GetAsync(int id)
{
return await _carDbContext.Cars.FindAsync(id);
}
}
更新:
private readonly ICarService _carService;
public CarController(ICarService carService)
{
_carService = carService;
}
public async Task<IActionResult> Get([FromRoute] int id)
{
var car = await _carService.GetAsync(id);
}
更新 2:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CarDbContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("Db")); });
services.AddTransient<ICarService, CarService>();
}
}
public class CarService : ICarService
{
private readonly CarDbContext _carDbContext;
public ContactService(CarDbContext carDbContext)
{
_carDbContext= carDbContext;
}
public async Task<Owner> GetAsync(int ownerId)
{
var owner = await _carDbContext.Owners.FindAsync(ownerId);
return owner.Car;
}
}
更新 3:
private readonly TestServer _server;
public Fixture()
{
var dbContextOptions = new DbContextOptionsBuilder<CarDbContext>()
.UseInMemoryDatabase(Guid.NewGuid().ToString())
.Options;
var mockContext = new Mock<CarDbContext>(dbContextOptions);
var mockOwnerSet = new Mock<DbSet<Owner>>();
var mockCarSet = new Mock<DbSet<Car>>();
mockContext.Setup(m => m.Owners).Returns(mockOwnerSet.Object);
mockContext.Setup(m => m.Cars).Returns(mockCarSet.Object);
var carService = new CarService(mockContext.Object);
_server = new TestServer(new WebHostBuilder()
.ConfigureAppConfiguration((context, conf) =>
{
conf.AddJsonFile(@Directory.GetCurrentDirectory() + "../appsettings.json");
}).UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddDbContext<CarDbContext>(options => options.UseInMemoryDatabase("Test"));
services.AddScoped<ICarService>(_ => carService);
})
);
Client = _server.CreateClient();
}
【问题讨论】:
-
有点不清楚你在问什么。你能分享一下
MyService的实现吗? -
你可以模拟 HTTPClient
-
@Johnny,我用服务实现更新了 q
-
如果您使用
HttpClient调用 API,这意味着您正在访问实际服务。如果您不打算使用实际服务,那么您应该只为CarService编写单元测试。 -
@user1672994 我确实有意访问 CarService 我只是想从它的 GetAsync 方法中伪造结果。
标签: c# asp.net-core .net-core integration-testing