使用Moq验证方法调用


142

我对使用C#进行单元测试和学习使用Moq相当陌生。下面是我要测试的课程。

class MyClass
{
    SomeClass someClass;
    public MyClass(SomeClass someClass)
    {
        this.someClass = someClass;     
    }

    public void MyMethod(string method)
    {
        method = "test"
        someClass.DoSomething(method);
    }   
}

class Someclass
{
    public DoSomething(string method)
    {
        // do something...
    }
}

以下是我的TestClass:

class MyClassTest
{
    [TestMethod()]
    public void MyMethodTest()
    {
        string action="test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();
        mockSomeClass.SetUp(a => a.DoSomething(action));
        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);
        mockSomeClass.Verify(v => v.DoSomething(It.IsAny<string>()));
    }
}

我得到以下异常:

Expected invocation on the mock at least once, but was never performed
No setups configured.
No invocations performed..

我只想验证是否正在调用方法“ MyMethod”。我想念什么吗?


1
如果SomeClass没有的定义(MyMethod(string)看起来好像没有),则不会编译。
白金天青

抱歉..我编辑了我的问题..
user591410 2012年

1
您的工作方向正确,但是发布的代码中存在错误。它不会编译-Someclass的大小写,DoSomething的返回无效。之后,您需要公共访问权限,然后将DoSomething设为虚拟。简而言之,您的生产代码中也可能存在错误。
TrueWill 2012年

感谢您的答复。我设置的参数错误在设置模拟方法..
user591410

“未配置任何设置。” 可能会产生误导。您无需为将要调用的方法设置行为。并且还记得在调用您要测试的方法之后执行“验证”方法(这样就可以了)。
西鲁

Answers:


208

您正在检查错误的方法。Moq要求您设置(然后选择验证)依赖项类中的方法。

您应该做更多这样的事情:

class MyClassTest
{
    [TestMethod]
    public void MyMethodTest()
    {
        string action = "test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();

        mockSomeClass.Setup(mock => mock.DoSomething());

        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);

        // Explicitly verify each expectation...
        mockSomeClass.Verify(mock => mock.DoSomething(), Times.Once());

        // ...or verify everything.
        // mockSomeClass.VerifyAll();
    }
}

换句话说,您正在验证调用MyClass#MyMethod,您的类肯定会SomeClass#DoSomething在该过程中调用一次。注意,您不需要Times参数。我只是在展示其价值。


抱歉,我用正确的方法编辑了问题。如您所述,我先尝试了SetUp,然后执行了Verify。它仍然给我同样的例外。
user591410 '02

22
设定期望值,然后明确验证相同的期望值是否多余?是否会mockSomeClass.VerifyAll();达到相同的结果,并且会更干燥?
Tim

13
是的,但是有些人喜欢露骨。
铂金天蓝色

3
至少感谢您提到VerifyAll(); 一旦想到就很明显。我可能会选择显式方法,但是在使用全部方法时会更清洁。谢天谢地,两个都列出了。
JGood

1
Mock相比的一个相关缺点NSubstitute是,如果您还尝试验证参数并且验证失败,那么它仅显示执行了哪些调用,但没有显示出如果在验证表达式中使用了变量确切地期望了什么-它只会显示变量名称,而不是其值,因此您需要调试以检查该变量的确切值。NSubstitute只会显示两者的值,甚至显示不同的值。
Grengas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.