Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot controller test - mock repository but test actual service

I'm trying to write a test class in Spring boot 2 where:

  • I want to test a controller
  • I want to mock a repository
  • I want to inject a service as is (i.e. without mocking it)

The class looks something like:

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTest {
    @Autowired
    private MockMvc mvc;
    @MockBean
    private MyRepositoryInterface myRepository;
    @Autowired
    private MyService myService;
    // tests follow ...
}

The (only) implementation of MyService is annotated with @Service and allows repository injection through its @Autowired constructor:

@Service
public class MyActualService implements MyService {
    private MyRepository repo;
    @Autowired
    public MyActualService(MyRepository repo) {
        this.repo = repo;
    }
    // ...
} 

I'm getting a NoSuchBeanDefinitionException when running the test, broadly stating "no MyService available".

I suspect I may require a specific configuration for the test to pick up the service, but I'm getting utterly confused by the online literature available.

Any pointer?

like image 943
Mena Avatar asked Jul 14 '18 17:07

Mena


1 Answers

After consulting the docs (I did not read properly in the first instance), as pointed out by jonsharpe, I managed to wrangle a working solution:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerTest {
    @Autowired
    private MockMvc mvc;
    @MockBean
    private MyRepositoryInterface myRepository;

    // no need to reference the service explicitly

    // ... tests follow
}

The above retrieves the service as it loads the full application configuration, and only mocks the repository as directed.

I could probably write an ad-hoc configuration to better fit the requirements, but this works "out of the box" already.

like image 118
Mena Avatar answered Oct 18 '22 07:10

Mena