GionJh
GionJh

Reputation: 2894

Mocking a bean in a Spring context

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

Answers (2)

Lorelorelore
Lorelorelore

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

Rishikesh Dhokare
Rishikesh Dhokare

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

Related Questions