Moq调用了一名代表

时间:2012-06-12 14:11:20

标签: c# unit-testing delegates moq

我得到了一个通过参数得到代表的类。 这个类调用该委托,我想用Moq对它进行单元测试。 我该如何验证是否已调用此方法?

示例类:

public delegate void Foo(int number);

public class A
{
   int a=5;

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

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

5 个答案:

答案 0 :(得分:46)

this commit开始,Moq现在支持嘲笑代表,根据你的情况,你会这样做:

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

答案 1 :(得分:30)

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

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

//do something
Assert.True(isDelegateCalled);

答案 2 :(得分:4)

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

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

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

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

锻炼后,您将能够验证对被模拟对象的期望。

更新:实际上,您只需将bar.Object.M传递给您的sut,而无需Foo代理实例创建。但无论如何,模拟代表需要创建界面。

答案 3 :(得分:3)

你可以这样做:

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

答案 4 :(得分:1)

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

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

提供的代理执行一些简单,可验证的操作。