如何在模拟方法中对函数进行单元测试
How to UnitTest a Function in a mocked method
如何在此处测试 DeleteAppointmentById?
Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
return _dataContextProvider.GetContextRW().Run(function);
_dataContextProvider 是用最小起订量模拟的。如果我 运行 测试它永远不会进入 DeleteAppointmentById 当然
测试方法:
public IEnumerable<uint> DeleteAppointment(uint appointmentId)
{
Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
return _dataContextProvider.GetContextRW().Run(function);
}
DeleteAppointmentById 是我真正感兴趣的内部方法(私有)。
我的测试:
[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
//Setup
var dbContextMock = new Mock<IDataContextProvider>();
var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();
dbContextMock.Setup(d => d.GetContextRW())
.Returns(dataAdapterMock.Object);
dataAdapterMock.Setup(a => a.Run(It.IsAny<Action<IDataAdapterRW>>()));
var calendarService = new CalendarService(dbContextMock.Object);
//Run
var result = calendarService.DeleteAppointment(1);
//Assert
Assert.AreEqual(1, result);
}
单元测试倾向于采用以下结构:
安排:设置上下文。在这种情况下,您可能会创建一个约会并将其保存到数据库中。
行动:调用您正在测试的单元。在这种情况下,DeleteAppointmentById(db, appointment).
断言:检查副作用和returns是否正确。在这种情况下,您可能会尝试从数据库加载此约会,并断言您不能(因为它应该已被删除)。
您可以将 Func
的 access the result 作为参数传递给 Run
方法,并向 断言 如下所示的结果。
为什么要return结果?因为它是一个 mock,并且不知道 Run
方法 的行为方式。
[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
//Setup
var dbContextMock = new Mock<IDataContextProvider>();
var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();
dbContextMock.Setup(d => d.GetContextRW())
.Returns(dataAdapterMock.Object);
dataAdapterMock.Setup(a => a.Run(It.IsAny<Func<IDataAdapterRW, IEnumerable<uint>>>()))
.Returns((Func<IDataAdapterRW, IEnumerable<uint>> func) => { return func(dataAdapterMock.Object);}); // configure the mock to return the list
var calendarService = new CalendarService(dbContextMock.Object);
//Run
int id = 1;
var result = calendarService.DeleteAppointment(id);
//Assert
var isInList = result.Contains(id); // verify the result if contains the
Assert.AreEqual(isInList, true);
}
如何在此处测试 DeleteAppointmentById?
Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
return _dataContextProvider.GetContextRW().Run(function);
_dataContextProvider 是用最小起订量模拟的。如果我 运行 测试它永远不会进入 DeleteAppointmentById 当然
测试方法:
public IEnumerable<uint> DeleteAppointment(uint appointmentId)
{
Func<IDataAdapterRW, IEnumerable<uint>> function = db => DeleteAppointmentById(db, appointmentId);
return _dataContextProvider.GetContextRW().Run(function);
}
DeleteAppointmentById 是我真正感兴趣的内部方法(私有)。
我的测试:
[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
//Setup
var dbContextMock = new Mock<IDataContextProvider>();
var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();
dbContextMock.Setup(d => d.GetContextRW())
.Returns(dataAdapterMock.Object);
dataAdapterMock.Setup(a => a.Run(It.IsAny<Action<IDataAdapterRW>>()));
var calendarService = new CalendarService(dbContextMock.Object);
//Run
var result = calendarService.DeleteAppointment(1);
//Assert
Assert.AreEqual(1, result);
}
单元测试倾向于采用以下结构:
安排:设置上下文。在这种情况下,您可能会创建一个约会并将其保存到数据库中。
行动:调用您正在测试的单元。在这种情况下,DeleteAppointmentById(db, appointment).
断言:检查副作用和returns是否正确。在这种情况下,您可能会尝试从数据库加载此约会,并断言您不能(因为它应该已被删除)。
您可以将 Func
的 access the result 作为参数传递给 Run
方法,并向 断言 如下所示的结果。
为什么要return结果?因为它是一个 mock,并且不知道 Run
方法 的行为方式。
[Test]
public void DeleteAppointment_Valid_DeletedRecordId()
{
//Setup
var dbContextMock = new Mock<IDataContextProvider>();
var dataAdapterMock = new Mock<IDataContext<IDataAdapterRW>>();
dbContextMock.Setup(d => d.GetContextRW())
.Returns(dataAdapterMock.Object);
dataAdapterMock.Setup(a => a.Run(It.IsAny<Func<IDataAdapterRW, IEnumerable<uint>>>()))
.Returns((Func<IDataAdapterRW, IEnumerable<uint>> func) => { return func(dataAdapterMock.Object);}); // configure the mock to return the list
var calendarService = new CalendarService(dbContextMock.Object);
//Run
int id = 1;
var result = calendarService.DeleteAppointment(id);
//Assert
var isInList = result.Contains(id); // verify the result if contains the
Assert.AreEqual(isInList, true);
}