代码之家  ›  专栏  ›  技术社区  ›  V0ldek

任何参数的nsubstitute-mock-out参数行为

  •  3
  • V0ldek  · 技术社区  · 6 年前

    我在嘲笑你 IConfigurationProvider 用N替代品。我需要方法 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; });
    

    但这并不能编译。 我需要mocked方法将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”填充它。

    1 回复  |  直到 6 年前
        1
  •  7
  •   Nkosi    6 年前

    configProvider.TryGet("key1", out Arg.Any<string>()) 不是有效的C语法,这就是它不会编译的原因。

    您需要为 外面的 参数。

    当测试时,以下操作有效。

    //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.
    
        2
  •  1
  •   Liam Joshua    5 年前

    从nsubstitute 4+开始,这是现成的支持:

    匹配out和ref参数

    参数匹配器也可以与out和ref一起使用(nsubstitute 4.0 之后是C 7.0和更高版本)。

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

    Source