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);
}
相關文章
相關標籤/搜索