V0l*_*dek 7 c# unit-testing nsubstitute .net-core
我正在尝试IConfigurationProvider使用NSubstitute。我需要该方法bool TryGet(string key, out string value)返回不同键的值。所以像这样:
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider.TryGet("key1", out Arg.Any<string>()).Returns(x => 
    { x[1] = "42"; return true; });
但这无法编译。我需要一个模拟方法来实际将out参数设置为适当的值,而不管该参数是什么-它是一个依赖项,被测单元使用自己的参数调用此方法,而我只是希望它“返回”(如通过填充out参数返回)正确的键值。
这应该为该问题提供更多视角:
var value = "";
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider
.TryGet("key1", out value)
.Returns(x => { 
    x[1] = "42"; 
    return true; 
});
var otherValue = "other";
configProvider.TryGet("key1", out value);
configProvider.TryGet("key1", out otherValue);
Assert.AreEqual("42", value);      // PASS.
Assert.AreEqual("42", otherValue); // FAIL.
我需要两个断言都是正确的,因为该方法将由测试的类使用,并且可以自由传递它想要的任何out参数,我只需要用“ 42”填充即可。
configProvider.TryGet("key1", out Arg.Any<string>()) 不是有效的C#语法,这就是为什么它不会编译的原因。
您需要为out参数使用实际变量。
经测试,以下工作。
//Arrange            
var expectedResult = true;
var expectedOut = "42";
var actualOut = "other";
var anyStringArg = Arg.Any<string>();
var key = "key1";
var configProvider = Substitute.For<IConfigurationProvider>();
configProvider
    .TryGet(key, out anyStringArg)
    .Returns(x => {
        x[1] = expectedOut;
        return expectedResult;
    });
//Act
var actualResult = configProvider.TryGet(key, out actualOut);
//Assert
Assert.AreEqual(expectedOut, actualOut); // PASS.
Assert.AreEqual(expectedResult, actualResult); // PASS.
从 NSubstitute 4+ 开始,这是开箱即用的支持:
匹配和引用参数
参数匹配器也可以与 out 和 ref 一起使用(NSubstitute 4.0 及更高版本与 C# 7.0 及更高版本一起使用)。
Run Code Online (Sandbox Code Playgroud)calculator .LoadMemory(1, out Arg.Any<int>()) .Returns(x => { x[1] = 42; return true; }); var hasEntry = calculator.LoadMemory(1, out var memoryValue); Assert.AreEqual(true, hasEntry); Assert.AreEqual(42, memoryValue);
确保记下上面使用的参数索引 ( x[1] = 42;),该数组包含输入和输出变量,但只能设置out变量的值。