day0ops
day0ops

Reputation: 7482

Mocking a autowired bean throws a NullPointerException

I have the following class structure in Spring.

BaseClass,

public abstract class BaseClass {

    @Autowired
    protected ServiceA serviceA;

    public final void handleMessage() {
        String str = serviceA.getCurrentUser();
    }
}

MyController,

@Component
public class MyController extends BaseClass {
    // Some implementation
    // Main thing is ServiceA is injected here
}

So far this works fine and I can see that the ServiceA being injected properly as well.

The problem is when mocking ServiceA in the test below.

MyControllerTest,

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class MyControllerTest {
    @MockBean
    private ServiceA serviceA;

    @MockBean
    private MyController myController;

    @Before
    public void init() {
        when(serviceA.getCurrentUser()).thenReturn(some object);
    }

    @Test
    public void firstTest() {
        myController.handleMessage(); // ---> Throws NPE stating that serviceA is null
    }
}

As indicated it throws a NullPointerException. I don't quite get why despite having when.thenReturn has no affect when mocking the bean.

Upvotes: 2

Views: 3722

Answers (1)

Beri
Beri

Reputation: 11610

Because you are using Spring controller, you need to import your controller from SpringContext, by @Autowired annotation:

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class MyControllerTest {
    @MockBean
    private ServiceA serviceA;

    @Autowired // import through Spring
    private MyController myController;

    @Before
    public void init() {
        when(serviceA.getCurrentUser()).thenReturn(some object);
    }

    @Test
    public void firstTest() {
        myController.handleMessage(); // ---> Throws NPE stating that serviceA is null
    }
}

@MockBean are added to SpringContext, so they will be injecte as a dependency to your controller.

Upvotes: 2

Related Questions