如何使用NSubstitute测试函数是否收到特定的委托?

时间:2017-02-14 18:01:00

标签: c# unit-testing delegates nunit nsubstitute

我想测试函数是否收到特定委托作为参数。是否可以在NUnit中使用NSubstitute?

我的界面:

public interface IMyInterface
{
    void Sort(Func<IEnumerable<int>, IOrderedEnumerable<int>> f);
}

我的测试班:

[TestFixture]
public class Class1
{
    [Test]
    public void Sort_WhenCalled_CallsWithPassedArgument()
    {
        // Arrange
        IMyInterface mock = Substitute.For<IMyInterface>();

        // Act
        mock.Sort(x => x.OrderBy(y => y));

        // Assert
        mock.Received().Sort(x => x.OrderBy(y => y));
    }
}

我也尝试过参数匹配器,但总是失败。

1 个答案:

答案 0 :(得分:0)

挑战在于您的参数类型是Func<>,而不是Expression<Func<>>。使用Expression,您可以检查树以检查方法名称等。

但是,您可以针对OrderBy的具体示例进行单元测试(例如,与OrderByDescending()相对,因为给定一组整数6,4 OrderBy()将始终重新将其排序为4,6。以下是有效的:

  [TestFixture]
  public class Class1
  {
    [Test]
    public void Sort_WhenCalled_CallsWithPassedArgument()
    {
      // Arrange
      IMyInterface mock = Substitute.For<IMyInterface>();

      Func<IEnumerable<int>, IOrderedEnumerable<int>> func = null;
      mock.WhenForAnyArgs(x => x.Sort(Arg.Any<Func<IEnumerable<int>, IOrderedEnumerable<int>>>())).Do(
        x =>
          {
            func = x.Arg<Func<IEnumerable<int>, IOrderedEnumerable<int>>>();
          });

      // Act
      mock.Sort(x => x.OrderBy(y => y));

      // Assert
      var result = func(new[] { 6, 4 });

      Assert.That(result.FirstOrDefault(), Is.Not.EqualTo(6));
      Assert.That(result.FirstOrDefault(), Is.EqualTo(4));
    }
  }

当然,逻辑有些脆弱,所以你需要决定是否真的要测试func中是否使用了一个精确的方法(然后可能重构代码以允许通过其他方法检查这个特定的方法或切换到Expression)或只是行为就足够了。