简体   繁体   English

Mockito间谍测试

[英]Mockito Spy Test

I am using Mockito to write tests for code. 我正在使用Mockito编写代码测试。 However I am stuck at following scenario - Class A has 2 methods, method1() and method2(). 但是我被困在以下场景中--A类有2个方法,method1()和method2()。 I tried using ArgumentCaptor to catch values sent to method2(). 我尝试使用ArgumentCaptor来捕获发送到method2()的值。 But, since I am using @Spy, I cannot use Matchers. 但是,由于我使用@Spy,我不能使用Matchers。

How do I test method1()? 我如何测试method1()?

class A{
    B b;
    method1(arg1, arg2){
       //some logic
       method2(arg1, arg2, ....argN);
    }

   method2(arg1, arg2,....argN){
       //some logic
       b.method3(arg1, arg2...);
   }
}

How to verify method2 receives same argument values? 如何验证method2是否收到相同的参数值? Following is the test class I wrote: 以下是我写的测试类:

Class TestA{

@Mock
B b;

@Spy
@InjectMocks   //required else b is null
A a = new A();

@Test
public void testMethod1(){

 a.method1(arg1, arg2);

  //How to verify method2 receives same argument values (arg1, arg2)????
  //verify(a, times(1)).method2(.......);   
}

} }

I was intrigued by this post and the comments left by @David so I decided to code a working example for those who follow like me 我被这篇文章和@David留下的评论所吸引,所以我决定为像我一样的人编写一个有效的例子

/*
 * class to test
 */
public class A {

    public void methodA(String str) {
        this.methodB(str);
    }

    protected void methodB(String str) {
        // some implementation
    }
}

We want to assert that the value being passed into methodB() is what we expect. 我们想断言传递给methodB()的值是我们所期望的。 Reading up on the ArgumentCaptor led me to discover the equivalent Captor Annotation 阅读ArgumentCaptor让我发现了等效的Captor Annotation

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MultipleMethodCallTest {

    @Spy
    A a = new A();

    @Captor ArgumentCaptor<String> captor;

    @Test
    public void captureSecondMethodCallArgument() throws Exception {

        // EXPECTED

        String greeting = "hello world";

        // PERFORM TEST

        a.methodA(greeting);

        // ASSERT

        verify(a).methodB(captor.capture());

        assertEquals(greeting, captor.getValue());
    }
}

This example was tested with 这个例子进行了测试

  • mockito-all-1.8.5.jar 的Mockito-ALL-1.8.5.jar
  • junit-4.8.2.jar JUnit的-4.8.2.jar

You cant, you have to verify it by B's method3 call. 你不能,你必须通过B的method3调用验证它。 If your args to method2 have no effect on method3, theses args could be useless at all?! 如果你对方法2的args对方法3没有影响,这些args可能根本就没用了!

You can use matchers with spies; 你可以使用间谍匹配; this works just fine. 这很好用。 I don't know why you thought that you couldn't. 我不知道为什么你认为你不能。

I took your source code and edited it to make it compile. 我拿了你的源代码并编辑它以使其编译。 I then added a call to MockitoAnnotations.initMocks - you need this to create the spy and the mock, and to inject the mock (unless you use the MockitoJUnitRunner , which does the initMocks for you). 然后我添加了对MockitoAnnotations.initMocks的调用 - 你需要这个来创建间谍和模拟,并注入模拟(除非你使用MockitoJUnitRunner ,它为你做initMocks )。 I put the verify of the call to method2 back in. This worked fine. 我把verify调用的method2在后面,这工作得很好。

So, contrary to Omnaest's answer, you don't need to use B's method3 to verify this. 因此,与Omnaest的答案相反,您不需要使用B的方法method3来验证这一点。 I suspect that your only problem was that you had forgotten the initMocks . 我怀疑你唯一的问题是你忘记了initMocks

Good luck with this, and feel free to post again if you need any more help. 祝你好运,如果你需要更多的帮助,请随时再发帖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM