从您发布的单元测试代码来看,您似乎对测试内容感到困惑。
查看您的类并确定您的“公共”接口,即可以从代码的其他部分调用哪些方法。您实际上应该只测试公共方法。私有方法通常通过公共方法进行测试。
看着AgeCategoryRequestHandler
,你有两个公共方法 -Run
and CreateResponse
。我想问是否CreateResponse
需要公开,但我们暂时保留它。对于这些方法中的每一个,您都希望断言返回值是给定输入值时所期望的值。
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
// Not needed
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
单元测试的设置正在以正确的方式进行 - 您已经为依赖项创建了模拟,但我看到您已经为要测试的类创建了模拟 - 这是不需要的,可以删除。您想要测试您在构造函数中初始化的实际类本身。
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
_logger.LogInformation("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository != null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories).ConfigureAwait(false);
}
_logger.LogInformation("AgeCategory requesthandler processrequest complete");
return 0;
}
我们可以测试公众Run
通过查看该方法并了解执行时它将执行的操作来了解该方法。首先,它将调用一个私有方法ProcessRequest
。里面ProcessRequest
, the IRepositoryResolver
将使用依赖关系。这意味着我们需要在单元测试中“设置”这种依赖关系以满足if (repository != null)
健康)状况。
我假设IRepositoryResolver
返回另一个接口(?) - 类似于:
public interface IRepository
{
Task<int> InsertUpdateEstabAgeCategoryDetail(List<int> x);
}
因此,在单元测试中,您需要为从返回的存储库创建一个模拟IRepositoryResolver
:
private readonly Mock<IRepository> _mockRepository = new Mock<IRepository>();
然后,您需要设置模拟IRepositoryResolver
返回上面的模拟存储库:
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
这是为了满足if (repository != null)
健康)状况。
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
接下来,您需要设置InsertUpdateEstabAgeCategoryDetail()
模拟存储库上的方法返回一个值。该值由以下方式返回ProcessRequest()
然后用来调用CreateResponse(inventoryRequest, result)
as the result
范围。
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = (int)OTAErrorType.InvalidAgeCategory;
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
现在您可以查看CreateResponse
方法并通过设置不同的值inventoryRequest.EstabAgeCategories
并设置模拟_mockRepository.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)).ReturnsAsync(6);
要返回不同的值,可以通过满足不同的路径if
陈述。
CreateResponse
正在返回一个实例HandlerResult
反过来又被返回Task<HandlerResult> Run
。这是您想要对其进行断言的返回对象。
其中一个单元测试用例可能如下所示(我自己没有测试过):
[Fact]
public async Task GivenInventoryRequest_WhenRun_ThenHandlerResultReturned()
{
// arrange
var inventoryRequest = new InventoryRequest
{
EstabAgeCategories = new List<int>
{
1, 2, 3, 4, 5
}
};
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 0);
Assert.True(result.ErrorCode == 0);
Assert.False(result.IsSuccess);
}