YLombardi
YLombardi

Reputation: 1795

Issue with Mockito and JpaRepository

I have a Spring boot project that I'm migrating to Spring boot 2. Some of my tests that where working with the previous version are failing with the new version.

The issue is easy to reproduce.

I create 2 Controller. In the first, I inject a Service. In the second, I inject a JpaRepository.

Now I create UnitTests for both this Controller. For the second Controller, I mock the Repository. Everything works fine. For the first Controller, I mock the Service. The test fail. It seems to search to inject the Repository whereas it is not used in this Controller.

I create a very simple project to reproduce this behavior : https://github.com/YLombardi/mockito-spring-jpa-issue

Is it my test that is wrong or a bug ?

Upvotes: 0

Views: 722

Answers (1)

Yogesh Badke
Yogesh Badke

Reputation: 4597

I was able to reproduce the issue from the repo url you gave. If you notice the exception when you run ControllerAUnitTests, it says

...UnsatisfiedDependencyException: Error creating bean with name 'controllerB'...

Now, why would spring try to load controllerB bean when you are running tests for ControllerA?

This is because you are using SpringRunner and default mockMvc. It loads whole spring context that means it will create beans of every component including controllerB.

To create the bean of controllerB, you need to have an instance of JpaRepo. So, just like you created mocked bean of ServiceA in ControllerAUnitTests, you need to create mocked bean for JpaRepo as well.

    @MockBean
    private ServiceA serviceA;

    // NOTE THIS BLOCK
    @MockBean
    private JpaRepo jpaRepo;

    @Test
    public void test() throws Exception {
        doReturn("a").when(serviceA).getAString();
        mockMvc.perform(get("/a"))
                .andDo(print())
                .andExpect(status().isOk())
                // Test now runs but assert fails below, that you need to fix.
                .andExpect(view().name("aview"))
                .andExpect(content().string("a"));
    }

Upvotes: 1

Related Questions