Reputation: 2894
I want to test a Spring bean A, of course this bean is part of a
context and it uses other beans to carry out operations.
There is a particular bean B in the context that I want to mock for this test, and note that B is not injected to A (I could handle this case easily with @InjectMocks
and @Mock
annotations), B is injected to C that is injected to D, that is injected to A.
Can I mock only B while testing class A? How can you accomplish this ?
Upvotes: 2
Views: 1860
Reputation: 3393
Assuming test class is annotated with @RunWith(MockitoJUnitRunner.class)
, you could try this:
@Mock
private B b;
@InjectMocks
@Spy
private C c = new C();
@InjectMocks
@Spy
private D d = new D();
@InjectMocks
private A a = new A();
Rapid explanation: B will be mocked. C and D will be created using new (no mock here, so we tag with @Spy
). @InjectMocks
will inject B in C, C in D and D in A. Hope it helps. A more complete example is available in this code of mine (just a sample application code) here. Notice how real objects and mocked objects are injected in the same class.
If you are using SpringRunner
, another way is:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {A.class, Bmock.class, C.class, D.class})
where Bmock.class
is a mock that you have already created somewhere in your project. This approach also assumes that you have correctly separated interfaces and implementations: it will work only if you autowire B interface in D, not B concrete class.
Upvotes: 2
Reputation: 3589
This is how your dependencies look like -
B -> C -> D -> A
Since you want to test Bean A, the only thing you would want to mock is D
and should not bother about what what D
needs. Mockito will do the job for you.
If for testing A
, you want to mock all the dependencies like B
and C
, you are doing it wrong.
Upvotes: 0