44

我有一个通过参数获得委托的类。这个类调用那个委托,我想用 Moq 对它进行单元测试。我如何验证这个方法是否被调用?

示例类:

public delegate void Foo(int number);

public class A
{
   int a = 5;

   public A(Foo myFoo)
   {
      myFoo(a);
   }
}

我想检查 Foo 是否被调用。谢谢你。

4

5 回答 5

65

这个提交起,起订量现在支持模拟代表,对于您的情况,您可以这样做:

var fooMock = new Mock<Foo>();
var a = new A(fooMock.Object);

然后您可以验证委托已被调用:

fooMock.Verify(f => f(5), Times.Once);

或者:

fooMock.Verify(f => f(It.IsAny<int>()), Times.Once);
于 2014-09-11T18:54:39.940 回答
37

使用匿名函数怎么样?它可以在这里像一个内联模拟,你不需要一个模拟框架。

bool isDelegateCalled = false;
var a = new A(a => { isDelegateCalled = true});

//do something
Assert.True(isDelegateCalled);
于 2012-06-12T14:41:33.893 回答
4

Moq 不支持模拟代表。但是您可以使用与您的委托签名匹配的方法创建一些接口:

public interface IBar
{
    void M(int number);
}

然后创建mock,它实现了这个接口,并使用这个mock对象来创建delegate:

Mock<IBar> bar = new Mock<IBar>();
Foo foo = new Foo(bar.Object.M); 
A a = new A(foo);
bar.Verify(x => x.M(5));   

练习完 sut 后,您将能够验证对模拟对象的期望。

更新:实际上您可以简单地传递bar.Object.M给您的 sut,而无需Foo创建委托实例。但无论如何,模拟委托需要创建接口。

于 2012-06-12T14:19:54.293 回答
4

你可以这样做:

 public interface IWithFOOMethod
 {
     void FooAlikeMethod(int number);
 }

 Mock<IWithFOOMethod> myMock = new Mock<IWithFOOMethod>();

 A a = new A(myMock.Object.FooAlikeMethod);

 myMock.Verify(call => call.Foo(It.IsAny<int>()), Times.Once())
于 2012-06-12T14:20:55.410 回答
1

由于 Moq 不支持模拟代表,我通常会使用以下方式处理此问题:

var list = new List<int> ();
var del = i => list.Add (i);
var a = new A(del);
list.ShouldContainOnly (new[] { 5 });

提供的委托执行一些简单的、可验证的操作。

于 2012-06-12T14:37:21.900 回答