Java模拟对象,无依赖注入

Java模拟对象,无依赖注入,java,unit-testing,junit,dependency-injection,mocking,Java,Unit Testing,Junit,Dependency Injection,Mocking,我对JUnit测试套件中的模拟对象感兴趣,但是我只遇到过使用依赖注入来注入模拟对象的模拟框架。但是,我希望能够模拟类/函数,而不必注入模拟对象,就像python中的@patch()一样 简单的例子: //dependency injection public String bar(Foo foo) { return foo.foo(); //just pass in mock Foo object } //.... onto test code Foo mockedFoo = <M

我对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>);
//依赖项注入
公共字符串栏(Foo-Foo){
返回foo.foo();//只需传入mock foo对象
}
//.... 关于测试代码
Foo mockedFoo=;
字符串响应=bar(mockedFoo);
assertEqual(应答,);
//我在找的案子
公共字符串条(){
Foo Foo=new Foo();//如何在此处创建模拟对象?
返回foo.foo();//或者仅仅是如何模拟单个函数?
}
//... 关于测试代码
字符串响应=bar();
assertEqual(应答,);

简单地说,你可以像这样模仿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);
    }
}
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);


}

}

当调用
new
时,您可以使用Powermock检测被测试的类以返回一个mock

您的代码如下所示:

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


}

}
RunWith(PowerMockRunner.class)
@准备测试(巴级)
公共类易货交易{
@试验
公开无效测试(){
Foo mockedFoo=createMock(Foo.class);
//在这里设置mockedFoo
...
//这将在Bar.class中调用new Foo()
//返回你的模拟,而不是一个真正的新的
expectNew(Foo.class).andReturn(mockedFoo);
...
重播(mockedFoo,File.class);
条形=新条形();
字符串响应=bar.bar();
assertEqual(应答,);
验证(mockedFoo,File.class);
}
}

使用库,例如Mockito。或者在更简单的情况下,扩展
Foo
,或者甚至更好,实现与
Foo
相同的接口,以获得一个简单的mock。Mike,从Mockito来看,似乎仍然需要注入依赖项。请参见上面的编辑以提高清晰度。@Kamoor1982,这篇文章的作者提出的问题似乎与我的要求相反。有人知道用c#代替java的解决方案吗?谢谢你的建议,修改了我的文章以提高清晰度。这个回答似乎回答了一个与我所问的稍有不同的问题,抱歉。如果我没有错的话,expectNew只在EasyMock中实现,而不是在Mockito中实现。对于Mockito,请使用whenNew。