Integration_Unit test coding standard

Integration & Unit test coding standard

命名规则

好的命名规则,直接从命名就能够清楚的知道该测试方法测试的内容和目的,而不用额外的添加注释说明。对于MVC而言,测试Controller是重点。c#

Testing Controller

对于Controller的测试,命名方式总共分为三段:session

Action_Return[_Condition]async

  • Action:Controller的Action
  • Return:指望的返回结果
  • Condition:在怎样的条件下

好比以下的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

单元测试能够帮助咱们Review Controller的职责

典型的controllers职责:string

  • 验证 ModelState.IsValid
  • 若是 ModelState 不合法,返回错误响应
  • 取得持久化的业务实体
  • 对业务实体采起行动
  • 持久化存储业务实体
  • 返回合适的 IActionResult

避免在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]

  • 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);
}
相关文章
相关标签/搜索