Java Mock 对象,无需依赖注入

我对JUnit测试套件中的模拟对象感兴趣,但是我只遇到过使用依赖注入来注入模拟对象的模拟框架。但是,我希望能够模拟类/函数,而不必注入该模拟对象,就像python中的@patch()一样。

简单示例:

//dependency injection
public String bar(Foo foo) {
    return foo.foo(); //just pass in mock Foo object
}
//.... onto test code
Foo mockedFoo = <Mocked Foo object>;
String response = bar(mockedFoo);
assertEqual(response, <mockedFoo return value>);


//case I am looking for
public String bar() {
    Foo foo = new Foo(); //how to create mock object here?
    return foo.foo(); //or simply how to mock a single function?
}
//... onto test code
<force the Foo class or foo method to be mocked from here without touching bar() source code>
String response = bar();
assertEqual(response, <mocked response>);

答案 1

您可以使用 Powermock 来检测所测试的类,以便在调用时返回模拟。new

Powermock 模拟构造函数教程

您的代码将如下所示:

RunWith(PowerMockRunner.class)
@PrepareForTest( Bar.class )
public class BarTest {


@Test
public void test(){
   Foo mockedFoo = createMock(Foo.class);
   //set up mockedFoo here
   ...

   //This will make a call  to new Foo() inside Bar.class
   //return your mock instead of a real new one
   expectNew(Foo.class).andReturn(mockedFoo);

   ...
   replay(mockedFoo, File.class);

   Bar bar = new Bar();
   String response = bar.bar();

   assertEqual(response, <mocked response>);

   verify(mockedFoo, File.class);


}

}

答案 2

简单地说,你可以像这样嘲笑Foo。

public String bar() {
    Foo foo = Mockito.mock(Foo.class);
    return foo.foo();
}

但这样做的问题是,这基本上不会做任何事情,因为当我们调用模拟版本时,您还没有定义应该返回的内容。使用一个更完整的示例,您可以执行如下操作:foo.foo()#foo()

class MyTest {

    Foo mockedFoo = Mockito.mock(Foo.class);

    @Before
    public void setUp() throws Exception {
        Mockito.when(mockedFoo.foo()).thenReturn("This is mocked!");
    }

    @Test
    public void testMock() {
        String returnedFoo = mockedFoo.foo();
        Assert.assertEquals("This is mocked!", returnedFoo);
    }
}

推荐