c# – 我的单元测试是否太在乎了
我对我的单元测试方法有两个顾虑:
>我在一种测试方法中测试过多吗? 我问自己,当我的方法名称是:ReturnInvalidModelState,然后我的其他两个断言是不正确的.至少关于方法名称…… [Test] public void Create_TemplateAlreadyExists_ReturnInvalidModelState() { // ARRANGE TemplateViewModel templateViewModel = new TemplateViewModel { Name = "MyTest" }; Mock<ITemplateDataProvider> mock1 = new Mock<ITemplateDataProvider>(); Mock<IMappingEngine> mock2 = new Mock<IMappingEngine>(); TemplateController controller = new TemplateController(mock1.Object,mock2.Object); mock1.Setup(m => m.TemplateExists("MyTest")).Returns(true); // Set ModelState.IsValid to false controller.ModelState.AddModelError("Name","This name already exists."); // ACT ActionResult result = controller.Create(templateViewModel); // ASSERT Assert.IsFalse(controller.ModelState.IsValid); Assert.IsInstanceOfType(typeof(PartialViewResult),result); Assert.AreEqual(templateViewModel,((PartialViewResult)result).Model); } [HttpPost] public ActionResult Create(TemplateViewModel templateViewModel) { if (ModelState.IsValid && !_templateDataProvider.TemplateExists(templateViewModel.Name)) { Template template = Mapper.Map<TemplateViewModel,Template>(templateViewModel); _templateDataProvider.AddTemplate(template); return new JsonNetResult(new { success = true }); } ModelState.AddModelError("Name","This name already exists."); return PartialView(templateViewModel); } 解决方法
是的,我认为你正在测试太多东西.
首先重命名您的测试方法.您的方法签名应描述操作,方案和预期结果. 如果我要重命名你的方法,那么最终会得到以下结果: public void Create_DuplicateTemplate_ModelStateIsInvalidAndReturnsPartialViewResultAndPartialViewResultOfTypeTemplateViewModel() { } 您的测试涉及三件事,而不是一件事.当它失败时,你不会马上知道它失败的原因. 考虑将其重新分解为较小的测试并封装一些排列逻辑,以便可以重复使用. 编辑: 关于单一测试方法的单一断言,您在评论中提出了一个很好的观点.我同意你的意见,尽管听起来不错,但通常还不够. 假设我有以下操作方法: [HttpPost] public ActionResult Register(NewUserViewModel newUser) { if (!ModelState.IsValid) return View(newUser); var newUserDTO = Mapper.Map<NewUserViewModel,NewUserDTO>(newUser); var userDTO = UserManagementService.RegisterUser(newUserDTO); var result = Mapper.Map<UserDTO,UserViewModel>(userDTO); TempData.Add("RegisteredUser",result); return RedirectToAction("RegisterSuccess"); } 我对此方法进行了以下单元测试: [TestMethod] public void Register_HttpPost_ValidViewModel_ReturnsRegisterSuccess() { // Arrange var autoMapperMock = this.mockRepository.DynamicMock<IMapper>(); var userManagementServiceMock = this.mockRepository.DynamicMock<IUserManagementService>(); var invalidRegistrationViewModel = new NewUserViewModel { LastName = "Lastname",FirstName = "Firstname",Username = null }; autoMapperMock.Expect(a => a.Map<UserDTO,UserViewModel>(Arg<UserDTO>.Is.Anything)).Repeat.Once().Return(null); autoMapperMock.Expect(a => a.Map<NewUserViewModel,NewUserDTO>(Arg<NewUserViewModel>.Is.Anything)).Repeat.Once().Return(null); userManagementServiceMock.Expect(s => s.RegisterUser(Arg<NewUserDTO>.Is.Anything)).Repeat.Once(); autoMapperMock.Replay(); var controller = new AccountController { Mapper = autoMapperMock,UserManagementService = userManagementServiceMock }; this.mockRepository.ReplayAll(); // Act var result = (RedirectToRouteResult)controller.Register(invalidRegistrationViewModel); // Assert Assert.IsTrue((string)result.RouteValues["Action"] == "RegisterSuccess"); } 如您所见,我对我的模拟设置了多个期望: >我希望AutoMapper被调用两次 在测试结束时,我有一个断言,检查用户是否被重定向到正确的路由. 那么我在哪里检查我的断言?我创建了另一种方法来确保满足我的期望: [TestCleanup] public void Cleanup() { try { this.mockRepository.VerifyAll(); } finally { } } 所以你是对的,我有三个断言而不是一个断言,但是我以这样的方式构造我的代码,所以看起来我只有一个断言. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |