如何使用 Moq 和 xUnit 测试异步方法
How to test async methods with Moq and xUnit
我有以下调用插入和更新方法的方法。
条件
在下面的 ProcessBspLoan
函数中,我调用了另一个名为 getBspData
的函数
如果 getBspData
returns 任何结果。我将插入结果
并且 更新 数据库作为特定 Id
的成功
如果 getBspData
抛出任何异常我只会 更新 数据库作为特定 ID 的失败而不 插入
这是给定的 class
中的 ProcessBspLoan 函数
public class BspLoanProcessor : IBspLoanProcessor
{
private readonly IBspClient _bspService;
private readonly IBspRepository _bspRepository;
private readonly ILogger<BspLoanProcessor> _logger;
private readonly IMapper _mapper;
private readonly IFhaRepository _fhaRepository;
public BspLoanProcessor(IBspClient bspService, ILogger<BspLoanProcessor> logger,
IMapper mapper, IBspRepository bSPRepository, IFhaRepository fhaRepository)
{
_bspService = bspService;
_logger = logger;
_mapper = mapper;
_bspRepository = bSPRepository;
_fhaRepository = fhaRepository;
}
public async Task<bool> ProcessBspLoan(BspLoanDetails bspLoanDetails, string transactionId, string triggerType)
{
FhaTransactionDetails fhaData = _mapper.Map<FhaTransactionDetails>(bspLoanDetails);
try
{
////////////////////////////Calling getBspData///////////////////////////////////////
var result = await _bspService.getBspData(bspLoanDetails.NsmLoanNumber, transactionId);
result.TransactionId = transactionId;
await _bspRepository.InsertBspResponse(result);
await _fhaRepository.UpdateFhaTransactionWithLoanNumber(transactionId,"SUCCESS");
return true;
}
catch(Exception ex)
{
await _fhaRepository.UpdateFhaTransactionWithLoanNumber(transactionId,"FAIL");
return false;
}
}
}
我为上述函数编写了测试方法,想根据提供的输入检查它是返回真还是假
这是我的测试函数
public async Task Test1Async()
{
Mock<IBspLoanProcessor> _bspLoanProcessor = new Mock<IBspLoanProcessor>();
Mock<IBspRepository> _bspRepository = new Mock<IBspRepository>();
Mock<IFhaRepository> _fhaRepository = new Mock<IFhaRepository>();
Mock<IBspClient> _bspClient = new Mock<IBspClient>();
BspLoanDetails bspLoanDetails = new BspLoanDetails
{
TriggerType = "BLOB",
Attempts = 1,
FirstRunDateTime = DateTime.Now.ToUniversalTime()
};
----> 1
_bspClient.Setup(x => x.getBspData(It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(new BspResponseDetails()));
----> 2
_bspRepository.Setup(x => x.InsertBspResponse(It.IsAny<BspResponseDetails>())).Returns(Task.CompletedTask);
----> 3
_fhaRepository.Setup(x => x.UpdateFhaTransactionWithLoanNumber(It.IsAny<string>(),It.IsAny<string>())).Returns(Task.CompletedTask);
bool value = await _bspLoanProcessor.Object.ProcessBspLoan(bspLoanDetails, "123", "SCHEDULE");
Assert.True(value);
}
在上面的测试中,我检查的是第一个条件
- 每当有人调用获取数据时,我都会将数据作为对象返回
- 插入
BspResponsemethod
我也回来了task.completedTask
UpdateFhaTransactionWithLoanNumber
我也回来了task.completedTask
实际预期输出为 true,但返回 false。
我是 Moq 和 xUnit 的新手。请帮助我解决这个问题并测试异步和等待方法。
IBspClient 接口
public interface IBspClient
{
Task<BspResponseDetails> getBspData(string loanNumber,string tid);
Task<BspHealthCheck> GetHealthStatus();
}
IBspRepository 接口
public interface IBspRepository
{
Task InsertBspResponse(BspResponseDetails bsp);
}
IFhaRepository 接口
public interface IFhaRepository
{
Task UpdateFhaTransactionWithLoanNumber(string tid, string status);
}
提前致谢
bool value = await _bspLoanProcessor.Object
您正在对模拟调用一个方法。你不应该模拟被测系统,你只模拟它的依赖关系。
只需 new
您想要测试的 class,否则您将测试您的模拟框架是否按照您的设置执行。
并且由于您没有设置 ProcessBspLoan()
,它 return 是其 return 值的默认值,因此 false
。
我有以下调用插入和更新方法的方法。
条件
在下面的
的成功ProcessBspLoan
函数中,我调用了另一个名为getBspData
的函数 如果getBspData
returns 任何结果。我将插入结果 并且 更新 数据库作为特定 Id如果
getBspData
抛出任何异常我只会 更新 数据库作为特定 ID 的失败而不 插入
这是给定的 class
中的 ProcessBspLoan 函数 public class BspLoanProcessor : IBspLoanProcessor
{
private readonly IBspClient _bspService;
private readonly IBspRepository _bspRepository;
private readonly ILogger<BspLoanProcessor> _logger;
private readonly IMapper _mapper;
private readonly IFhaRepository _fhaRepository;
public BspLoanProcessor(IBspClient bspService, ILogger<BspLoanProcessor> logger,
IMapper mapper, IBspRepository bSPRepository, IFhaRepository fhaRepository)
{
_bspService = bspService;
_logger = logger;
_mapper = mapper;
_bspRepository = bSPRepository;
_fhaRepository = fhaRepository;
}
public async Task<bool> ProcessBspLoan(BspLoanDetails bspLoanDetails, string transactionId, string triggerType)
{
FhaTransactionDetails fhaData = _mapper.Map<FhaTransactionDetails>(bspLoanDetails);
try
{
////////////////////////////Calling getBspData///////////////////////////////////////
var result = await _bspService.getBspData(bspLoanDetails.NsmLoanNumber, transactionId);
result.TransactionId = transactionId;
await _bspRepository.InsertBspResponse(result);
await _fhaRepository.UpdateFhaTransactionWithLoanNumber(transactionId,"SUCCESS");
return true;
}
catch(Exception ex)
{
await _fhaRepository.UpdateFhaTransactionWithLoanNumber(transactionId,"FAIL");
return false;
}
}
}
我为上述函数编写了测试方法,想根据提供的输入检查它是返回真还是假
这是我的测试函数
public async Task Test1Async()
{
Mock<IBspLoanProcessor> _bspLoanProcessor = new Mock<IBspLoanProcessor>();
Mock<IBspRepository> _bspRepository = new Mock<IBspRepository>();
Mock<IFhaRepository> _fhaRepository = new Mock<IFhaRepository>();
Mock<IBspClient> _bspClient = new Mock<IBspClient>();
BspLoanDetails bspLoanDetails = new BspLoanDetails
{
TriggerType = "BLOB",
Attempts = 1,
FirstRunDateTime = DateTime.Now.ToUniversalTime()
};
----> 1
_bspClient.Setup(x => x.getBspData(It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(new BspResponseDetails()));
----> 2
_bspRepository.Setup(x => x.InsertBspResponse(It.IsAny<BspResponseDetails>())).Returns(Task.CompletedTask);
----> 3
_fhaRepository.Setup(x => x.UpdateFhaTransactionWithLoanNumber(It.IsAny<string>(),It.IsAny<string>())).Returns(Task.CompletedTask);
bool value = await _bspLoanProcessor.Object.ProcessBspLoan(bspLoanDetails, "123", "SCHEDULE");
Assert.True(value);
}
在上面的测试中,我检查的是第一个条件
- 每当有人调用获取数据时,我都会将数据作为对象返回
- 插入
BspResponsemethod
我也回来了task.completedTask
UpdateFhaTransactionWithLoanNumber
我也回来了task.completedTask
实际预期输出为 true,但返回 false。
我是 Moq 和 xUnit 的新手。请帮助我解决这个问题并测试异步和等待方法。
IBspClient 接口
public interface IBspClient
{
Task<BspResponseDetails> getBspData(string loanNumber,string tid);
Task<BspHealthCheck> GetHealthStatus();
}
IBspRepository 接口
public interface IBspRepository
{
Task InsertBspResponse(BspResponseDetails bsp);
}
IFhaRepository 接口
public interface IFhaRepository
{
Task UpdateFhaTransactionWithLoanNumber(string tid, string status);
}
提前致谢
bool value = await _bspLoanProcessor.Object
您正在对模拟调用一个方法。你不应该模拟被测系统,你只模拟它的依赖关系。
只需 new
您想要测试的 class,否则您将测试您的模拟框架是否按照您的设置执行。
并且由于您没有设置 ProcessBspLoan()
,它 return 是其 return 值的默认值,因此 false
。