如何解决如何在单元测试控制器最小起订量上下文中跳过调用函数?
这是我的控制器
BusinessLayer.Lookup.Lookup_Rooms RoomsBL = new BusinessLayer.Lookup.Lookup_Rooms();
[HttpPost]
public ActionResult CreateRoom(UMIS_Portal_BackEnd.Areas.StudentAcadimic.Models.RoomLocationModel room) {
if (ModelState.IsValid)
{
try
{
// Todo: Add insert logic here
int? Serial = RoomsBL.Lookup_RoomInsert(room.BuildingFloorID,room.RoomName,room.Min_Capacity,room.Max_Capacity);
}
catch (Exception error)
{
ViewBag.Messages = error.InnerException.Message;
}
}
return View();
}
我只想测试这个动作结果是否存在视图,所以我写了这段代码
[TestMethod()]
public void CreateRoomTestPost()
{
LookupRoomsController controller = new LookupRoomsController();
UMIS_Portal_BackEnd.Areas.StudentAcadimic.Models.RoomLocationModel room = new UMIS_Portal_BackEnd.Areas.StudentAcadimic.Models.RoomLocationModel();
ViewResult viewResult = controller.CreateRoom(room) as ViewResult;
Assert.IsNotNull(viewResult);
}
我希望测试跳过调用
int? Serial = RoomsBL.Lookup_RoomInsert(room.BuildingFloorID,room.Max_Capacity);
关于主控制器动作。
解决方法
问题在于控制器与实现细节紧密耦合
BusinessLayer.Lookup.Lookup_Rooms RoomsBL = new BusinessLayer.Lookup.Lookup_Rooms();
而不是将抽象显式注入其中。创建其依赖项不是控制器的责任。 (单一职责原则 (SRP) 和关注点分离 (Soc))
Lookup_Rooms
需要抽象化
public interface ILookup_Rooms {
//...
}
public class Lookup_Rooms : ILookup_Rooms {
//...
}
以及显式注入控制器的抽象。
private readonly BusinessLayer.Lookup.ILookup_Rooms RoomsBL;
//CTOR
public LookupRoomsController(ILookup_Rooms RoomsBL) {
this.RoomsBL = RoomsBL;
}
[HttpPost]
public ActionResult CreateRoom(RoomLocationModel room) {
if (ModelState.IsValid) {
try {
// TODO: Add insert logic here
int? Serial = RoomsBL.Lookup_RoomInsert(room.BuildingFloorID,room.RoomName,room.Min_Capacity,room.Max_Capacity);
} catch (Exception error) {
ViewBag.Messages = error.InnerException.Message;
}
}
return View();
}
这样,当在隔离的单元测试中调用 Lookup_RoomInsert
时,可以使模拟对象不执行任何操作。
[TestMethod()]
public void CreateRoomTestPost() {
// Arrange
ILookup_Rooms mock = Mock.Of<ILookup_Rooms>(); //using MOQ
LookupRoomsController controller = new LookupRoomsController(mock);
RoomLocationModel room = new RoomLocationModel();
// Act
ViewResult viewResult = controller.CreateRoom(room) as ViewResult;
// Assert
Assert.IsNotNull(viewResult);
}
最后,抽象和实现应该注册到一个 DI 容器中,这样实际的实现才能在系统在生产中运行时正确地注入到控制器中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。