我在实体框架中有一个模型。我想确保应用程序服务正在读取正确指向数据库的通用存储库。我有点被困在Xunit中如何测试呢?收到以下错误,也许我需要重写代码。需要验证App服务可以读取InMemory数据库中下面的示例数据行。
型号:
public partial class Department
{
public int DepartmentId { get; set; }
public string DepartmentCode { get; set; }
public string DepartmentName { get; set; }
.... plus additional
}
DTO:
public class DepartmentDto
{
public int DepartmentId { get; set; }
public string DepartmentCode { get; set; }
public string DepartmentName { get; set; }
}
来自IRepository的基础存储库:
public async Task<T> GetAsync(int id)
{
return await Table.FindAsync(id);
}
**Constructor:**
public BaseRepository(DbContext context)
{
_context = context;
Table = _context.Set<T>();
}
服务:DepartmentAppService.cs
public async Task<DepartmentDto> GetDepartmentById(int id)
{
var department = await departmentRepository.GetAsync(id);
var departmentDto = mapper.Map<Department, DepartmentDto>(department);
return departmentDto;
}
**Constructor:**
public DepartmentAppService(IRepository<Department> departmentRepository, IMapper mapper)
{
this.departmentRepository = departmentRepository;
this.mapper = mapper;
}
尝试的测试代码:
public async Task Get_DepartmentById_Are_Equal()
{
var options = new DbContextOptionsBuilder<TestContext>()
.UseInMemoryDatabase(databaseName: "TestDatabase")
.Options;
var context = new TestContext(options);
Mock<IRepository<Department>> departmentRepositoryMock = new Mock<IRepository<Department>>();
Mock<IMapper> mapperMock = new Mock<IMapper>();
Mock<DepartmentAppService> departmentAppServiceMock = new Mock<DepartmentAppService>(departmentRepositoryMock, mapperMock);
context.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" });
var test = await departmentAppServiceMock.GetDepartmentById(5);
Assert.Equal("123", test.DepartmentCode);
接收错误:如何解决?
'Mock<DepartmentAppService>' does not contain a definition for 'GetDepartmentById' and no accessible extension method 'GetDepartmentById' accepting a first argument of type 'Mock<DepartmentAppService>' could be found (are you missing a using directive or an assembly reference?)
程序中也有依赖项注入。打开以根据需要重写的代码,
答案 0 :(得分:0)
您不想创建DepartmentAppService
的模拟。您要创建一个实例。您要测试的方法需要真实对象的实例,而不是模拟对象。您想测试实际对象的代码,模拟不运行任何代码,而仅返回伪数据。
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(sharedServicesProfile);
});
mapper = config.CreateMapper();
var departmentAppService = new DepartmentAppService(departmentRepositoryMock.Object, mapperMock.Object);
如果您使用的是InMemory数据库,并且实际上是从该InMemory数据库获取存储库的数据,则您也不想模拟存储库,因为您正在访问物理数据库并返回真实数据而不是模拟数据
说实话,我认为您需要阅读更多有关测试和模拟的信息。似乎缺少了一些核心概念...这是一种编写您尝试做的事情的方法。
AutoMapper.Mapper.Initialize(m => m.AddProfile<YOUR AUTOMAPPER PROFILE>());
AutoMapper.Mapper.AssertConfigurationIsValid();
var options = new DbContextOptionsBuilder<TestContext>()
.UseInMemoryDatabase(databaseName: "TestDatabase")
.Options;
var context = new TestContext(options))
context.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" });
context.SaveChanges();
var departmentRepository = new Repository<Department>>(context);
var departmentAppService = new DepartmentAppService(departmentRepository, mapper);
var test = await departmentAppService.GetDepartmentById(5);
Assert.Equal("123", test.DepartmentCode);
您可能还想考虑布置上下文或将其包装在使用中。如果复制粘贴后代码无法正确运行,则可能需要进行一些调整,但应该相当接近。
从上面的代码中可以看到,您仍然需要学习何时模拟和何时不模拟!不需要模拟。您也正在进行集成测试,如果您不想进行集成测试,则可以删除上下文内容并模拟存储库,并设置模拟以返回部门。