嘲笑类方法在Java中不起作用
附加了代码及其测试下面:
public class A {
private B b;
public A(C c) {
b = new B(c);
}
public ResponseOutput method1(RequestInput request) {
ResponseOutput responseOutput = b.method2(param1, param2);
//Do something based on responseOutput. e.g. throwException if some condition meet
return responseOutput;
}
}
public class ATest {
@Mock
private C c;
@Mock
private B b;
@InjectMocks
private A a;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void method1_test1() {
ResponseOutput responseOutput = something;
Mockito.when(b.method2(Mockito.any(), Mockito.any())).thenReturn(responseOutput);
a.method1(param1, param2);
}
}
B.Method2没有被模拟。呼叫将用于内部功能。嘲笑B类所需的其他注释还需要其他注释。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,@InjectMocks将创建模拟对象(每次运行@Test方法时创建一个新对象)
但是,您没有使用该创建的实例 - 而是直接在@before方法中创建一个新实例。 @InjectMocks对创建的实例没有影响。
因此,您需要决定,您是否要使用创建的@InjectMocks,还是要使用自己的实例(在这种情况下,您必须设置B自己 - 也许使用PowerMock模拟新呼叫,或者使用使用Mockito 嘲笑测试类内的新实例创建类)。
此外,@InjectMocks仍将无法为您设置B @InjectMocks在@mock声明之后。
First, @InjectMocks will create the mock object (creating a new object every time an @Test method is run)
However, you are not using that created instance - instead you are creating a new instance directly in your @Before method. @InjectMocks has no effect on that created instance.
So you need to decide, do you want to use the @InjectMocks created instance of A, or do you you want to use your own (in which case, you must set b yourself - maybe using PowerMock to mock the new call, or alternatively use ideas from Mocking new instance creation inside testing class using mockito ).
In addition, @InjectMocks will still not set b for you, because Java initialises objects in order of declaration, which results in @InjectMocks only being able to inject @Mock variables declared before it - so you would have to switch the ordering around to have @InjectMocks AFTER the @Mock declarations.
@InjectMock
将尝试使用最大的构造函数来创建和注入模拟的依赖关系(请参阅此有关详细信息它的行为)在您的情况下是:现在您在此构造函数内部手动创建一个B实例,该构造函数在A内部导致B是真实的实例,而不是模拟的实例。因此,您对模拟B的固执没有任何效果,因为A没有调用它。
实际上,A仅需要直接与B互动,因此您无需模拟C。第一个重构A可以直接使用B直接创建:
然后将测试更新为:
请注意,您必须从A中删除constructor
public a(c c)
。 > @InjectMocks 只会随机选择public a(c c)
或public a(b b)
创建一个,因为两者都是最大的构造函数。如果您不想删除constructor
public a(c c)
,请勿使用@injectMocks
创建一个,但只需自己创建它:@InjectMock
will try to use the biggest constructor to create and inject the mocked dependencies into A .(Refer this for detail of its behaviour) which in your case is :Now you manually create a B instance inside this constructor which causes B inside A is a real instance but not a mocked one. So what you stub on the mocked B does not have any effect because A is not calling it.
Actually , A only needs to directly interact with B and so you do not need to mock C . First refactor A such that it can be directly created using B only :
And then update the test to :
Please note that you have to remove the constructor
public A(C c)
from A. Otherwise ,@InjectMocks
will just randomly choosepublic A(C c)
orpublic A(B b)
to create A because both are the biggest constructors.If you do not want to remove constructor
public A(C c)
, don't use@InjectMocks
to create A but simply create it by yourself :