如何创建用于在存储库中添加项目的单元测试?
How to Create a Unit Test for Adding Items in a Repository?
我有一个 IUnitOfWork 接口封装了我的自定义存储库。我的自定义存储库又继承自 IRepository 接口。
// The class that I am attempting to unit test
// EmployeeBusiness.cs
private readonly IUnitOfWork _unitOfWork;
public EmployeeBusiness(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public EmployeeDto AddEmployee(EmployeeDto employeeDto)
{
var employee = Mapper.Map<Employee>(employeeDto);
if (employee == null) return null;
_unitOfWork.Employees
.Add(employee);
_unitOfWork.Complete();
return Mapper.Map<EmployeeDto>(employee);
}
// IUnitOfWork interface
public interface IUnitOfWork : IDisposable
{
IEmployeeRepository Employees { get; }
void Complete();
}
// IEmployeeRepository interface
public interface IEmployeeRepository : IRepository<Employee> { }
// IRepository<T> interface
public interface IRepository<TEntity> where TEntity : class
{
void Add(TEntity entity);
// I have added other methods for simplicity
}
我正在努力对 AddEmployee()
方法进行单元测试,因为我收到此错误:
预期对模拟调用一次,但为 0 次:uow => uow.Employees.Add(Employee)
配置的设置:
IUnitOfWork uow => uow.Employees.Add(员工)
执行的调用:
IRepository`1.Add(员工)
这是我的单元测试
[SetUp]
public void SetUp()
{
_employeeDto = new EmployeeDto
{
FirstName = "John",
LastName = "Smith",
BirthDate = new DateTime(1965, 12, 31)
};
_employee = new Employee
{
FirstName = "John",
LastName = "Smith",
BirthDate = new DateTime(1965, 12, 31)
};
_unitOfWork = new Mock<IUnitOfWork>();
Mapper.Initialize(cfg =>
{
cfg.AddProfile<EmployeeProfile>();
});
}
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
_employeeBusiness.AddEmployee(_employeeDto);
_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once);
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
您没有检查 AddEmployee
的 return 值。
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
var result = _employeeBusiness.AddEmployee(_employeeDto);
Assert.IsNotNull(result); // <---
_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once);
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
我已经通过更改我的单元测试设法让它工作
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
var result = _employeeBusiness.AddEmployee(_employeeDto);
//_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once); <-- This did not work
_unitOfWork.Verify(uow => uow.Employees.Add(It.IsAny<Employee>()), Times.Once); // <-- After changing this to It.IsAny<Employee>() it worked
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
谁能帮我理解使用 It.IsAny<Employee>()
和 _employee
变量的区别?
更新
可以在 找到解释。
您在答案中提供的测试(复制在下方)在您的原始测试失败时通过的原因是因为您的原始测试期望使用您正在使用的特定参考变量(在本例中为 _employee)调用模拟。也许您希望 Moq 和 .Verify() 使用 .equals() 而不是 ==?
检查是否相等
在您的被测方法的上下文中,这是正确且可取的 - 根据您要测试的测试名称,该方法实际上确实将您的输入映射到 Employee 并调用存储库的添加方法。如果你想确保数据在映射中没有丢失,你可以使用 It.Is(),它带有一个函数,你可以用它来断言输入的质量(比如名称匹配你的期望值) .
如果您只是想测试映射是否成功,您可能会对 Automapper Configuration Validation 作为单独的测试感兴趣。
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
var result = _employeeBusiness.AddEmployee(_employeeDto);
//_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once); <-- This did not work
_unitOfWork.Verify(uow => uow.Employees.Add(It.IsAny<Employee>()), Times.Once); // <-- After changing this to It.IsAny<Employee>() it worked
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
我有一个 IUnitOfWork 接口封装了我的自定义存储库。我的自定义存储库又继承自 IRepository 接口。
// The class that I am attempting to unit test
// EmployeeBusiness.cs
private readonly IUnitOfWork _unitOfWork;
public EmployeeBusiness(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public EmployeeDto AddEmployee(EmployeeDto employeeDto)
{
var employee = Mapper.Map<Employee>(employeeDto);
if (employee == null) return null;
_unitOfWork.Employees
.Add(employee);
_unitOfWork.Complete();
return Mapper.Map<EmployeeDto>(employee);
}
// IUnitOfWork interface
public interface IUnitOfWork : IDisposable
{
IEmployeeRepository Employees { get; }
void Complete();
}
// IEmployeeRepository interface
public interface IEmployeeRepository : IRepository<Employee> { }
// IRepository<T> interface
public interface IRepository<TEntity> where TEntity : class
{
void Add(TEntity entity);
// I have added other methods for simplicity
}
我正在努力对 AddEmployee()
方法进行单元测试,因为我收到此错误:
预期对模拟调用一次,但为 0 次:uow => uow.Employees.Add(Employee) 配置的设置: IUnitOfWork uow => uow.Employees.Add(员工) 执行的调用: IRepository`1.Add(员工)
这是我的单元测试
[SetUp]
public void SetUp()
{
_employeeDto = new EmployeeDto
{
FirstName = "John",
LastName = "Smith",
BirthDate = new DateTime(1965, 12, 31)
};
_employee = new Employee
{
FirstName = "John",
LastName = "Smith",
BirthDate = new DateTime(1965, 12, 31)
};
_unitOfWork = new Mock<IUnitOfWork>();
Mapper.Initialize(cfg =>
{
cfg.AddProfile<EmployeeProfile>();
});
}
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
_employeeBusiness.AddEmployee(_employeeDto);
_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once);
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
您没有检查 AddEmployee
的 return 值。
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
var result = _employeeBusiness.AddEmployee(_employeeDto);
Assert.IsNotNull(result); // <---
_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once);
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
我已经通过更改我的单元测试设法让它工作
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
var result = _employeeBusiness.AddEmployee(_employeeDto);
//_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once); <-- This did not work
_unitOfWork.Verify(uow => uow.Employees.Add(It.IsAny<Employee>()), Times.Once); // <-- After changing this to It.IsAny<Employee>() it worked
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}
谁能帮我理解使用 It.IsAny<Employee>()
和 _employee
变量的区别?
更新
可以在
您在答案中提供的测试(复制在下方)在您的原始测试失败时通过的原因是因为您的原始测试期望使用您正在使用的特定参考变量(在本例中为 _employee)调用模拟。也许您希望 Moq 和 .Verify() 使用 .equals() 而不是 ==?
检查是否相等在您的被测方法的上下文中,这是正确且可取的 - 根据您要测试的测试名称,该方法实际上确实将您的输入映射到 Employee 并调用存储库的添加方法。如果你想确保数据在映射中没有丢失,你可以使用 It.Is(),它带有一个函数,你可以用它来断言输入的质量(比如名称匹配你的期望值) .
如果您只是想测试映射是否成功,您可能会对 Automapper Configuration Validation 作为单独的测试感兴趣。
[Test]
public void AddEmployee_WhenCalled_AddEmployeeToDatabase()
{
_unitOfWork.Setup(uow => uow.Employees.Add(_employee));
_employeeBusiness = new EmployeeBusiness(_unitOfWork.Object);
var result = _employeeBusiness.AddEmployee(_employeeDto);
//_unitOfWork.Verify(uow => uow.Employees.Add(_employee), Times.Once); <-- This did not work
_unitOfWork.Verify(uow => uow.Employees.Add(It.IsAny<Employee>()), Times.Once); // <-- After changing this to It.IsAny<Employee>() it worked
_unitOfWork.Verify(uow => uow.Complete(), Times.Once);
}