带有可选参数的模拟方法根据可选默认值返回意外的不同值

问题描述 投票:0回答:1

我模拟了一个接口中的方法,该方法具有可选参数来返回

true

但是,根据我是将所有可选参数传递给调用还是仅传递必需参数,我会得到不同的结果。

这是该行为的完整工作示例:

using Moq;
using System.Threading;
using System.Threading.Tasks;
using Xunit.Abstractions;
namespace MoqTest
{
    public interface IProcedureService
    {
        Task<bool> InterfaceMethod(string req1, int req2, int? opt1 = null, CancellationToken opt2 = default);
    }
    public class Tests
    {
        Mock<IProcedureService> _procedureService = new Mock<IProcedureService>();
        ITestOutputHelper _output;
        public Tests(ITestOutputHelper output) => _output = output;

        [Xunit.Fact]
        public async void DoTheTest()
        {
            _procedureService.Setup(x => x.InterfaceMethod(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
                .ReturnsAsync(true);

            _output.WriteLine($"result from IsUniqueProcedureNameInWorkspace (using optional defaults) " +
                $"{(await _procedureService.Object.InterfaceMethod("", 0))}"); // returns false
            _output.WriteLine($"result from IsUniqueProcedureNameInWorkspace (NOT using optional defaults) " +
                $"{(await _procedureService.Object.InterfaceMethod("", 0, 0, default))}"); // returns true
        }
    }
}

输出以下内容:

Standard Output: 
result from IsUniqueProcedureNameInWorkspace (using optional defaults) False
result from IsUniqueProcedureNameInWorkspace (NOT using optional defaults) True

当我为设置中的所有参数设置

True
时,我希望它们都会返回
It.IsAny

我在这里缺少什么?

我的最小起订量版本是 4.20.70

c# unit-testing moq
1个回答
0
投票

确实正如乔恩·斯基特(Jon Skeet)已经建议的那样,但由于我在阅读问题时已经有了这个想法(所以在看到他的评论之前),而且由于我也不厌其烦地重现了这个问题,所以我冒昧地将以下内容写为答案而不是评论。

我不依赖于要检查的输出,而是提供解决方案作为测试,使用断言来证明修复有效:

[Fact]
public async Task FixWithAssertions()
{
    _procedureService
        .Setup(x => x.InterfaceMethod(
            It.IsAny<string>(),
            It.IsAny<int>(),
            It.IsAny<int?>(),
            It.IsAny<CancellationToken>()))
        .ReturnsAsync(true);

    var result1 = await _procedureService.Object.InterfaceMethod("", 0);
    var result2 = await _procedureService.Object.InterfaceMethod("", 0, 0, default);

    Assert.True(result1);
    Assert.True(result2);
}

我在

Setup
中唯一改变的就是我指出了
It.IsAny<int?>()
而不是
It.IsAny<int>()
。正如 Jon 所写,这些不是同一类型,这可以解释为什么
Setup
没有捕获省略可选值的调用。

© www.soinside.com 2019 - 2024. All rights reserved.