好的命名规则,直接从命名就能够清楚的知道该测试方法测试的内容和目的,而不用额外的添加注释说明。对于MVC而言,测试Controller是重点。c#
对于Controller的测试,命名方式总共分为三段:session
Action_Return[_Condition]async
好比以下的Controller:单元测试
public class AdminUserController : Controller { public async Task<IActionResult> Details(string id)
单元测试方法命名以下:测试
[Fact] public async Task Details_ReturnViewResult_WhenExitsUserId() [Fact] public async Task Details_ReturnNotFoundViewResult_WhenNotExitsUserId()
集成测试方法命名以下;ui
[Fact] public async Task Details_ReturnDetailsPage_WhenExitsUserId() [Fact] public async Task Details_ReturnNotFound_WhenNotExitsUserId()
另外,对于需求:Admin帐号登陆以后,菜单额外显示Admin菜单,单元测试没法作到,必需要用集成测试:code
[Fact] public async Task Login_ReturnHomePageWithAdminMenu_WhenIsAdmin()
集成测试要比单元测试慢几个数量级,因此能用单元测试验证的地方,就不要用集成测试orm
典型的controllers职责:string
避免在controllers中添加没必要要的职责,以及保证测试仅仅集中在controller的职责,测试controllers的逻辑,在合法和不合法的输入下的行为,而不是检测其余的方法是否正确,举个例子:it
[HttpPost] public async Task<IActionResult> Index(NewSessionModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } await _sessionRepository.AddAsync(new BrainstormSession() { DateCreated = DateTimeOffset.Now, Name = model.SessionName }); return RedirectToAction("Index"); }
单元测试以下:
[Fact] public async Task IndexPost_ReturnsBadRequest_WhenModelStateIsInvalid() { // Arrange var mockRepo = new Mock<IBrainstormSessionRepository>(); mockRepo.Setup(repo => repo.ListAsync()).Returns(Task.FromResult(GetTestSessions())); var controller = new HomeController(mockRepo.Object); controller.ModelState.AddModelError("SessionName", "Required"); var newSession = new HomeController.NewSessionModel(); // Act var result = await controller.Index(newSession); // Assert var badRequestResult = Assert.IsType<BadRequestObjectResult>(result); Assert.IsType<SerializableError>(badRequestResult.Value); }
注意上面的测试主动给controller的ModelState添加了Error,而不是等Controller的ModelState.IsValid方法来判断Model是否输入了SessionName,ModelState.IsValid是否能够正常工做是集成测试负责的内容,单元测试只要负责检测 !ModelState.IsValid 时,是否返回BadRequest!单元测试要作的是,覆盖到Controller的每个Return!
对于通常公用方法的测试,命名方式总共分为三段:
Action_Return[_Condition]
好比一个用来检测奇数偶数的类:
public class OddEvenNumberChecker { public bool IsOdd(int number); public bool IsEven(int number); }
单元测试以下:
public class OddEvenNumberCheckerTest { [Fact] public void IsOdd_ReturnTrue_When1357(); [Fact] public void IsOdd_ReturnFalse_When2468(); [Fact] public void IsEven_ReturnFalse_When1357(); [Theory] [InlineData(2)] [InlineData(4)] [InlineData(6)] [InlineData(8)] public void IsEven_ReturnTrue_When2468(int value); }