【问题标题】:NSubstitute: Received() does not check string parameter when string comes from resourceNSubstitute:当字符串来自资源时,Received() 不检查字符串参数
【发布时间】:2016-12-17 19:49:18
【问题描述】:

我将NSubstitute 用于我的NUnit 测试,并尝试检查是否使用正确的值调用了方法。直到知道一切正常。我必须本地化文本,因此为此使用资源字符串。现在每个单元测试都失败了,它测试要接收的方法,其中字符串参数包含一个新行。

这是一个简化的例子:

// Old Version, where the unit test succeed
public void CallWithText(ICallable callable)
{
    callable.ShowText("Some text with a new\nline."); 
}

// New Version, where the unit test fails
// Text of `Properties.Resources.TextWithNewLine` in the
// Resources.resx is "Some text with a new
// line."
public void CallWithText(ICallable callable)
{
    callable.ShowText(Properties.Resources.TextWithNewLine); 
}

[Test]
public void CallWithText_WhenCalled_CallsCallable()
{
    var caller = new Caller();
    var callable = Substitute.For<ICallable>();

    caller.CallWithText(callable);

    callable.Received(1).ShowText("Some text with a new\nline.");
}

对我来说,新行似乎有问题。有没有人有解决方案,因为调整所有单元测试是一团糟。

【问题讨论】:

  • 请发帖minimal reproducible example。还要发布失败的测试的输出。您确定资源文件只包含一个换行符而不包含换行符吗?
  • 你是对的(就像@Alexandr Niktin),资源文件包含\r\n,这就是测试失败的原因。

标签: c# string unit-testing nunit nsubstitute


【解决方案1】:

问题与NSubstitute 无关,而与String 本身有关。新的线符号不仅仅是\n。它是特定于环境的:\r\n 在 Windows 上,\n 在 Unix 上,\r 在早期的 Mac OS 上。请使用 Shift+Enter 在资源管理器中正确添加新行。

你有几种使用方法:

  1. Environment.NewLine 属性,它知道当前环境的换行符:

    callable.Received(1).ShowText("Some text with a new" + Environment.NewLine + "line.");
    
  2. 在预期的字符串中使用明确的换行:

    callable.Received(1).ShowText(@"Some text with a new
    line.");
    

【讨论】:

    【解决方案2】:

    在单元测试中比较确切的字符串会增加更多的维护工作。
    在您的情况下,new line 在不同的执行环境中可能会有所不同。

    对于字符串,我建议使用Contains 方法断言传递的参数。您可以在哪里查看更重要的字词

    [Test]
    public void CallWithText_WhenCalled_CallsCallable()
    {
        var caller = new Caller();
        var callable = Substitute.For<ICallable>();
    
        caller.CallWithText(callable);
    
        callable.Received(1).ShowText(Arg.Is<string>(text => text.Contains("Some text")));
    }
    

    【讨论】:

      【解决方案3】:

      这表示Properties.Resources.TextWithNewLine"Some text with a new\nline."不同。在不太了解Properties.Resources.TextWithNewLine的情况下,建议你尝试将测试改为

      [Test]
      public void CallWithText_WhenCalled_CallsCallable()
      {
          var caller = new Caller();
          var callable = Substitute.For<ICallable>();
      
          caller.CallWithText(callable);
      
          callable.Received(1).ShowText(Arg.Any<string>());
      }
      

      如果你真的想断言字符串的内容,或者使用实际的字符串,更改为(确保资源文件在测试项目中)

      [Test]
      public void CallWithText_WhenCalled_CallsCallable()
      {
          var caller = new Caller();
          var callable = Substitute.For<ICallable>();
      
          caller.CallWithText(callable);
      
          callable.Received(1).ShowText(Properties.Resources.TextWithNewLine);
      }
      

      【讨论】:

      • 感谢您的回答。由于示例被简化,原始示例中的参数值是复合的。通过测试,我还想测试参数的值是否正确计算。所以在我的情况下,你的两个继任者都不起作用。
      • @scher 您能否在 OP 中提供更多信息以反映这一点?
      • 感谢您的工作,抱歉我没有详细解释问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多