简体   繁体   English

如何为返回值取决于输入的相同方法设置最小起订量?

[英]How to setup Moq for the same method where return value depends on input?

I'd like to test a method called multiple times during test, in a way where the tested method output depends on its input.我想测试一个在测试过程中多次调用的方法,测试方法的输出取决于它的输入。 I checked Moq's documentation and the following example seems to what I need.我检查了 Moq 的文档,下面的例子似乎是我需要的。

// matching Func<int>, lazy evaluated
mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true);

The tested method looks like this:测试方法如下所示:

Task<DimensionStructure> GetDimensionStructureByIdAsync(DimensionStructure dimensionStructure);

The DimensionStructure class looks like this, it is simplified as on the Id is important. DimensionStructure 类看起来像这样,它被简化为对Id很重要。

public class DimensionStructure
    {
        public long Id { get; set; }
    }

But when I put together the mock I need, example below, when it is called it returns always null .但是当我把我需要的模拟放在一起时,下面的例子,当它被调用时,它总是返回null

_masterDataWebApiClientMock.Setup(m => m.GetDimensionStructureByIdAsync(
                    It.Is<DimensionStructure>(
                        structure => structure.Id == 101)
                ))
               .ReturnsAsync(addedToRoot);
_masterDataWebApiClientMock.Setup(m => m.GetDimensionStructureByIdAsync(
                    It.Is<DimensionStructure>(
                        structure => structure.Id == 201 )
                ))
               .ReturnsAsync(addedToFirstLevel);

The point os that the method gets different parameter and returns different objects.该方法获取不同参数并返回不同对象的点os。 In both cases, it returns null .在这两种情况下,它都返回null According to the doc, it should return what is in the ReturnAsync which is not null.根据文档,它应该返回ReturnAsync中不为空的内容。

It works perfectly in another test where the Id property value of the object doesn't matter.它在另一个测试中完美地工作,其中对象的Id属性值无关紧要。

_masterDataWebApiClientMock.Setup(m => m.GetDimensionStructureByIdAsync(It.IsAny<DimensionStructure>()))
               .ReturnsAsync(addedDimensionStructure);

The question is, how to solve this?问题是,如何解决这个问题?

Update - 02/29/2020更新 - 02/29/2020

When I do not specify the call parameter then it is just working fine.当我不指定调用参数时,它就可以正常工作。 It makes a bit tricky to test the method, but solvable.测试该方法有点棘手,但可以解决。

_masterDataWebApiClientMock
               .Setup(m => m.GetDimensionStructureByIdAsync(
                    It.IsAny<DimensionStructure>()
                ))
               .ReturnsAsync(addedToRoot);

On the other hand I reported this case a special, possible bug case to Moq folks.另一方面,我向 Moq 人员报告了这个案例,这是一个特殊的、可能的错误案例。

Having put together a test bench as follows I can see it returns correct values.按如下方式组合一个测试台后,我可以看到它返回正确的值。 It seems either my assumptions about IClassUnderTest are wrong or you might need to ensure addedToRoot and addedToFirstLevel are defined when you call your mocked method .似乎我对IClassUnderTest假设是错误的,或者您可能需要确保在调用addedToFirstLevel方法时定义了addedToRootaddedToFirstLevel

This probably doesn't answer your question per se, I'm however hoping this will either point you in the right direction or will prompt for more information.这本身可能并不能回答您的问题,但是我希望这可以为您指明正确的方向或提示您提供更多信息。

using System;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq; //I'm running Moq 4.13 

namespace UnitTestProject1
{
    public class DimensionStructure
    {
        public long Id { get; set; }
    }

    public interface ITest
    {
        Task<DimensionStructure> GetDimensionStructureByIdAsync(DimensionStructure dimensionStructure);
    }

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var addedToRoot = new DimensionStructure { Id = 1 };
            var addedToFirstLevel = new DimensionStructure { Id = 2 };

            var _masterDataWebApiClientMock = new Mock<ITest>();
            _masterDataWebApiClientMock.Setup(m => m.GetDimensionStructureByIdAsync(
                    It.Is<DimensionStructure>(
                        structure => structure.Id == 101)
                ))
                .ReturnsAsync(addedToRoot);
            _masterDataWebApiClientMock.Setup(m => m.GetDimensionStructureByIdAsync(
                    It.Is<DimensionStructure>(
                        structure => structure.Id == 201)
                ))
                .ReturnsAsync(addedToFirstLevel);


            Assert.AreEqual(1, _masterDataWebApiClientMock.Object.GetDimensionStructureByIdAsync(new DimensionStructure { Id = 101 }).Result.Id);
            Assert.AreEqual(2, _masterDataWebApiClientMock.Object.GetDimensionStructureByIdAsync(new DimensionStructure { Id = 201 }).Result.Id);
        }
    }
}

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

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