Java 如何模拟来自Junit的内部方法调用

Java 如何模拟来自Junit的内部方法调用,java,junit,mocking,mockito,Java,Junit,Mocking,Mockito,我有我的类,我正在为每个方法做一个测试类(Method1Test) 问题是我无法模拟对method2的调用以使其返回不同的值。莫基托的句子不起作用 非常感谢^ ^最后,我找到了一个横向解决方案,但没有创建新类(我无法做到这一点,因为它在实际项目中是不允许的)。我在测试中重写了该方法 解决办法是 public class MyClass { public int method1(){ int a=0; a=method2(); return

我有我的类,我正在为每个方法做一个测试类(Method1Test)

问题是我无法模拟对method2的调用以使其返回不同的值。莫基托的句子不起作用


非常感谢^ ^

最后,我找到了一个横向解决方案,但没有创建新类(我无法做到这一点,因为它在实际项目中是不允许的)。我在测试中重写了该方法

解决办法是

public class MyClass {
    public int method1(){
        int a=0;
        a=method2();
        return a;
    }
    public int method2(){
        return 1;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class Method1Test {
    @InjectMocks
    private MyClass myClass = new MyClass(){
        public int method2(){
            return 25;
        }
    };
    @Before
    public void setup(){}
    @Test
    public void test001(){
        Mockito.when(myClass.method2()).thenReturn(25);
        int a = myClass.method1();
        assertTrue("We did it!!!",a==25);
    }
}

您必须在被测试的类上创建一个spy,并通过重新定义spy的
method2()
的行为对其进行部分模拟

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;


public class Method1Test {

  private MyClass myClass = new MyClass();

  @Test
  public void test01(){
    //given
    MyClass spy = spy(myClass); //create a spy for class-under-test
    when(spy.method2()).thenReturn(25); //partially override behavior of the spy
    //when
    int a = spy.method1(); //make the call to method1 of the _spy_!
    //then
    assertEquals(25, a);
  }
}
除此之外,您的测试既不需要Mockito运行程序也不需要
@InjectMocks
,因为您没有将
@Mock
注释的Mock注入到被测试的类中


此外,
assertTrue
语句中的消息仅在断言条件未满足时显示。所以至少应该是“我们失败了!!!”;)

我使用下面的代码尝试了解决方案,但没有通过

Mockito.when(myClass.method2()).thenReturn(25);
之后,我尝试了一些不同的方法,而不是上面的代码片段,测试成功通过。看一看:

Mockito.doReturn(25).when(myClass).method2();
为了模拟测试(可能是内部方法),必须使用doReturn()方法

对于任何方法,都可以使用doThrow()、doAnswer()、doNothing()、doReturn()和doCallRealMethod()代替when()的相应调用。当你

  • 存根空洞法
  • spy对象上的存根方法(见下文)
  • 不止一次地使用相同的方法,以在测试中间更改模拟的行为。
但您可能更愿意使用这些方法来代替替代方法 使用when(),用于所有存根调用

此外,可以在这里阅读信息,而不是使用mock(class),这里我们需要使用Mockito.spy()来模拟我们正在测试的同一个类。然后我们可以模拟我们想要的方法,如下所示

@Test

  public void method1Test() { 

  MyClass myClass = new MyClass();

  MyClass myClass1 = Mockito.spy(myClass);

  Mockito.doReturn(1).when(myClass1).method2();

  Assert.assertEquals(1, myClass1.method1());

     }
 }

从技术上讲,您正在创建一个新类,尽管它是一个匿名类。但是你现在所做的和你自己写模拟一样,就像在前模拟时代一样。所以,在我看来,我不同意你的解决方案,因为你只在测试中重写了这个方法。您能想象测试不同的方法并覆盖每个方法吗?这很尴尬。
@Test

  public void method1Test() { 

  MyClass myClass = new MyClass();

  MyClass myClass1 = Mockito.spy(myClass);

  Mockito.doReturn(1).when(myClass1).method2();

  Assert.assertEquals(1, myClass1.method1());

     }
 }