Java模拟-用模拟对象动态替换类
我希望在运行时用mock替换类的所有实例。这可能吗?例如,在一个测试中,我想将Java模拟-用模拟对象动态替换类,java,unit-testing,mocking,Java,Unit Testing,Mocking,我希望在运行时用mock替换类的所有实例。这可能吗?例如,在一个测试中,我想将classbar标记为模拟类。在测试范围内,在类Foo的构造函数中,newbar()应该返回Bar的模拟实例,而不是真正的类 class Bar { public int GiveMe5() { return 5; } } public class Foo { private Bar bar; Foo() { bar = new Bar();
classbar
标记为模拟类。在测试范围内,在类Foo
的构造函数中,newbar()
应该返回Bar
的模拟实例,而不是真正的类
class Bar {
public int GiveMe5() {
return 5;
}
}
public class Foo {
private Bar bar;
Foo() {
bar = new Bar();
}
}
然后在我的测试中:
class TestFoo {
@Before
public void setUp() {
// Tell the mocking framework every instance of Bar should be replaced with a mocked instance
}
@Test
private void testFoo() {
Foo foo = new Foo(); // Foo.bar should reference a mocked instance of Bar()
}
}
您可以在Mockito中模拟新实例来完成复杂的事情,但是简单地注入测试所需的依赖项要简单得多
public class Foo {
private Bar bar;
Foo(Bar bar) {
this.bar = bar;
}
}
此时,您可以将想要的
Bar
的任何实例注入此类,包括mock。您可以在Mockito中模拟新实例来完成复杂的事情,但是简单地注入测试中所需的依赖项要简单得多
public class Foo {
private Bar bar;
Foo(Bar bar) {
this.bar = bar;
}
}
此时,您可以将所需的
Bar
的任何实例注入此类,包括mock。尝试PowerMockito和whenNew方法。当调用Foo类的构造函数时,您应该能够返回一个模拟实例。尝试PowerMockito和whenNew方法。当调用Foo类的构造函数时,您应该能够返回一个模拟实例。您可以使用一个支持模拟“新建”(未来)对象的模拟库来执行此操作。JMockit和PowerMock都支持它。例如,使用JMockit时,测试如下所示:
public class FooTest {
@Test
public void mockAllInstancesOfAClass(@Mocked Bar anyBar) {
new Expectations() {{ anyBar.giveMe5(); result = 123; }};
Foo foo = new Foo();
// call method in foo which uses Bar objects
// asserts and/or verifications
}
}
您可以使用模拟库来实现这一点,该库支持模拟“新的”(未来)对象。JMockit和PowerMock都支持它。例如,使用JMockit时,测试如下所示:
public class FooTest {
@Test
public void mockAllInstancesOfAClass(@Mocked Bar anyBar) {
new Expectations() {{ anyBar.giveMe5(); result = 123; }};
Foo foo = new Foo();
// call method in foo which uses Bar objects
// asserts and/or verifications
}
}
这类事情通常是通过依赖注入来完成的。那么
setBar(Bar)
方法呢。这将是最简单的解决方案,但您也可以通过反射进行设置。这类事情通常通过依赖项注入来完成。那么setBar(Bar)
方法呢。这将是最简单的解决方案,但您也可以通过反射进行设置。实际上,我必须传播这种依赖注入并更改我的生产代码,以便运行测试。PowerMockito whenNew基本上就是我想要做的。如果Bar
是一个真实的对象,也就是说,如果它在构造函数中初始化了实例状态(newbar(1,“data”)
,那么这种方法就不起作用了。这样的对象不能通过DI注入。@Rogério:关键是在注入Bar
时,要完全远离这种模式。上面的代码过于简单了。实际上,我必须传播这种依赖注入并更改我的生产代码,以便运行测试。PowerMockito whenNew基本上就是我想要做的。如果Bar
是一个真实的对象,也就是说,如果它在构造函数中初始化了实例状态(newbar(1,“data”)
,那么这种方法就不起作用了。这样的对象不能通过DI注入。@Rogério:关键是在注入Bar
时要完全远离这种模式。