【问题标题】:How to test async methods with Moq and xUnit如何使用 Moq 和 xUnit 测试异步方法
【发布时间】:2020-07-13 09:27:44
【问题描述】:

我有以下调用插入和更新方法的方法。

条件

  1. 在下面的ProcessBspLoan 函数中,我正在调用另一个名为getBspData 的函数 如果getBspData 返回任何结果。我将插入结果 并更新数据库作为特定 ID 的成功

  2. 如果getBspData 抛出任何异常,我将只更新数据库作为特定 ID 的失败,而不插入

这是给定类中的 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);
    }

在上面的测试中,我检查的是第一个条件

  1. 每当有人调用获取数据时,我都会将数据作为对象返回
  2. 插入BspResponsemethod 我也返回task.completedTask
  3. UpdateFhaTransactionWithLoanNumber 我也回来了task.completedTask

实际的预期输出为真,但返回的是假。

我是 Moq 和 xUnit 的新手。请帮我解决这个问题并测试 async 和 await 方法。

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);    
    }

提前致谢

【问题讨论】:

  • 什么是'_mapper'?我认为它是一个“Automapper”(或类似的)实例,定义了如何将源映射到目标。如果是,从标准的角度来看,不应该将其注入“ProcessBspLoan”的方法签名中吗?我正在尝试您的代码,但意识到映射器对象成为无法从外部注入测试的依赖项。除非你在课堂上照顾它。另外,您能否提供其他依赖项的定义,例如存储库和 _bspService 类等?
  • _mapper 是一个自动映射器,我正在处理类级 public BspLoanProcessor(IBspClient bspService, ILogger logger, IMapper mapper, IBspRepository bSPRepository, IFhaRepository fhaRepository) { _bspService = bspService; _logger = 记录器; _mapper = 映射器; _bspRepository = bSPRepository; _fhaRepository = fhaRepository; }
  • 确定我会编辑问题并提供每个界面

标签: c# asp.net-core moq xunit


【解决方案1】:

bool value = await _bspLoanProcessor.Object

你在你的模拟上调用一个方法。你不应该模拟被测系统,你只模拟它的依赖关系。

只需 new 您要测试的类,否则您将测试您的模拟框架是否符合您的设置。

因为你没有设置ProcessBspLoan(),所以它返回默认值,所以false

【讨论】:

  • 哦好的,我会检查一次
  • 谢谢知识转移
猜你喜欢
  • 2021-06-16
  • 2015-02-13
  • 1970-01-01
  • 2018-01-26
  • 2020-12-01
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 2016-01-04
相关资源
最近更新 更多