Core Components of Unit Testing
Unit testing involves creating isolated tests for individual code components. The process includes setting up test projects, analyzing interface behaviors under various conditions, and providing appropriate input parameters.
3A Testing Pattern
The standard approach for structuring unit tests follows the Arrange-Act-Assert pattern:
- Arrenge: Prepare test dependencies and inputs
- Act: Execute the method under test
- Assert: Verify expected outcomes
Example Controller Method
[HttpPost]
[Route("api/Account/GetEpVIPInfo")]
public object GetEpVIPInfo(GetEpVIPInfoRequest input)
{
var response = new BaseResponse
{
Info = Constants.FailureMessage,
Message = Constants.FailureMessage,
Success = false,
ResultCode = Constants.FailureCode
};
var vipDetail = new VIPDetailModel();
var vipData = AccountService.GetEpVIPInfo(input);
if (vipData != null)
{
vipDetail.VIPLevelId = DetermineVIPLevel(vipData.Name);
}
else
{
vipDetail.VIPLevelId = 0;
}
response = new BaseResponse
{
Info = vipDetail,
Message = Constants.SuccessMessage,
Success = true,
ResultCode = Constants.SuccessCode
};
return response;
}
Corresponding Unit Tests
#region GetEpVIPInfo Tests
[TestMethod]
public void GetEpVIPInfo_InvalidParameters_ReturnsSuccessResponse()
{
// Arrange
var controller = new AccountController();
var mockService = new Mock<IAccountService>();
mockService.Setup(s => s.GetEpVIPInfo(It.IsAny<GetEpVIPInfoRequest>()))
.Returns((VIPRecord)null);
controller.AccountService = mockService.Object;
// Act
var testRequest = new GetEpVIPInfoRequest { CityCode = "3202", EnterpriseId = -1 };
var testResult = controller.GetEpVIPInfo(testRequest);
var responseData = testResult.GetResponseModel();
// Assert
Assert.IsTrue(responseData.Success);
Assert.AreEqual(Constants.SuccessMessage, responseData.Message);
Assert.AreEqual(Constants.SuccessCode, responseData.ResultCode);
}
[TestMethod]
public void GetEpVIPInfo_ValidParameters_ReturnsCorrectVIPData()
{
// Arrange
var controller = new AccountController();
var mockService = new Mock<IAccountService>();
mockService.Setup(s => s.GetEpVIPInfo(It.IsAny<GetEpVIPInfoRequest>()))
.Returns(new VIPRecord { Name = "Monthly Member", Id = 4 });
controller.AccountService = mockService.Object;
// Act
var testRequest = new GetEpVIPInfoRequest { CityCode = "3202", EnterpriseId = 1 };
var testResult = controller.GetEpVIPInfo(testRequest);
var responseData = testResult.GetResponseModel();
var expectedDetail = new VIPDetailModel { VIPLevelId = 4 };
// Assert
Assert.IsTrue(responseData.Success);
Assert.AreEqual(Constants.SuccessMessage, responseData.Message);
Assert.AreEqual(Constants.SuccessCode, responseData.ResultCode);
Assert.AreEqual(expectedDetail.ToJson(), responseData.Info.ToJson());
}
#endregion
Test Organization Practices
Using #region blocks helps organize test methods by functionality, making code navigation and maintenance more efficient. Each interface method should have tests covering all possible execution paths and edge cases.
Note: Paramter validation is handled at the interceptor level in this architecture, preventing null or missing parameter requests from reaching the controller methods.