简体   繁体   English

如何使用 Moq 和 xUnit 测试异步方法

[英]How to test async methods with Moq and xUnit

I am having the following method which calls an insert and update methods.我有以下调用插入和更新方法的方法。

Conditions条件

  1. In the below ProcessBspLoan function, I am calling other function named getBspData if getBspData returns any result.在下面的ProcessBspLoan function 中,如果getBspData返回任何结果,我正在调用其他名为getBspData function。 I will insert the result and update the database as a success for a particular Id我将插入结果并将数据库更新为特定 ID 的成功

  2. if getBspData throws any Exception I will only update the database as a fail for a particular Id without inserting如果getBspData抛出任何异常,我只会将数据库更新为特定 ID 的失败而不插入

Here is the ProcessBspLoan function in the given class这是给定 class 中的 ProcessBspLoan function

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

I wrote the test method for the above function want to check it is returning true or false based on inputs provided我为上述 function 编写了测试方法,想根据提供的输入检查它是返回真还是假

Here is my test function这是我的测试 function

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

In the above the test, I am checking the first condition在上面的测试中,我正在检查第一个条件

  1. I am returning data as an object whenever anyone called gets data每当有人调用获取数据时,我都会以 object 的形式返回数据
  2. Inserting BspResponsemethod also I am returning task.completedTask插入BspResponsemethod我也返回task.completedTask
  3. UpdateFhaTransactionWithLoanNumber also I am returning task.completedTask UpdateFhaTransactionWithLoanNumber我也返回task.completedTask

The actual expected output is true, but it is returning false.实际预期的 output 为 true,但它返回 false。

I am new to Moq and xUnit.我是 Moq 和 xUnit 的新手。 Please help me to resolve this issue and also test async and await methods.请帮我解决这个问题,并测试 async 和 await 方法。

IBspClient interface IBspClient 接口

    public interface IBspClient
    {
        Task<BspResponseDetails> getBspData(string loanNumber,string tid);

        Task<BspHealthCheck> GetHealthStatus();
    }

IBspRepository Interface IBspRepository 接口

    public interface IBspRepository
    {
        Task InsertBspResponse(BspResponseDetails bsp);
    }

IFhaRepository interface IFhaRepository 接口

    public interface IFhaRepository
    {
        Task UpdateFhaTransactionWithLoanNumber(string tid, string status);    
    }

Thanks in advance提前致谢

bool value = await _bspLoanProcessor.Object

You're calling a method on your mock.你在你的模拟上调用一个方法。 You shouldn't mock the system-under-test, you only mock its dependencies.你不应该模拟被测系统,你只模拟它的依赖关系。

Just new the class you want to test, otherwise you will be testing that your mock framework does what you set it up to.只需new您要测试的 class,否则您将测试您的模拟框架是否符合您的设置。

And because you didn't setup ProcessBspLoan() , it returns the default for its return value, so false .而且因为您没有设置ProcessBspLoan() ,所以它返回其返回值的默认值,因此false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM