Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have two classes of tests: 1- for the unit test of the Controller class and 2- for the unit test of the Service class as below:

1- Test class controller:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class CentroDeCustoRestControllerTeste {
    @Autowired
    private MockMvc mvc;
    @MockBean
    private CentroDeCustoService service;
    @Test
    @WithMockUser(username = "[email protected]", authorities = {"ADMIN"})
    public void aoBuscarUmCentroDeCustoRetornarUmJsonComPropriedadeCentroDeCusto() throws Exception {
        CentroDeCusto centroDeCusto = new CentroDeCusto();
        centroDeCusto.setNome("Financeiro");
        given(service.centroDeCusto(1L)).willReturn(Optional.of(centroDeCusto));
        mvc.perform(get("/centrosdecustos/1").contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.centroDeCusto", org.hamcrest.core.Is.is(centroDeCusto.getCentroDeCusto())));

2- Test class Service:

@RunWith(SpringRunner.class)
public class CentroDeCustoServiceImplTeste {
    @TestConfiguration
    static class CentroDeCustoServiceImplConfiguracaoContexto {
        @Bean
        public CentroDeCustoService centroDeCustoService() {
            return new CentroDeCustoServiceImpl();
    @Autowired
    private CentroDeCustoService service;
    @MockBean
    private CentroDeCustoRepository repository;
    @Before
    public void setup() {
        CentroDeCusto centroDeCusto = new CentroDeCusto();
        centroDeCusto.setId(1L);
        Optional<CentroDeCusto> centroDeCustoOpt = Optional.of(centroDeCusto);
        Mockito.when(repository.findById(1L)).thenReturn(centroDeCustoOpt);
    @Test
    public void aoBuscarUmCentroDeCustoExistenteRetornarUmCentroDeCustoOptional() {
        Optional<CentroDeCusto> resultado = service.centroDeCusto(1L);
        CentroDeCusto centroDeCusto = resultado.get();
        Assertions.assertThat(centroDeCusto.getId())
                .isEqualTo(1L);

Interface CentroDeCustoService

public interface CentroDeCustoService {
    Optional<CentroDeCusto> centroDeCusto(Long id);
    Page<CentroDeCusto> centrosDeCusto(Pageable pagina);
    Optional<CentroDeCusto> buscaCentroDeCustoPeloNumero(String numero);
    List<CentroDeCusto> buscaCentrosDeCustoDeUmaContaGerencial(Long idDaContaGerencial);
    boolean verificaSeCentroDeCustoJahExiste(CentroDeCusto centroDeCusto);
    CentroDeCusto criaCentroDeCusto(CentroDeCusto centroDeCusto);
    CentroDeCusto atualizaCentroDeCusto(CentroDeCusto centroDeCusto);
    boolean delataCentroDeCusto(Long id);

Class CentroDeCustoServiceImpl

@Service
public class CentroDeCustoServiceImpl implements CentroDeCustoService {
    @Autowired
    private CentroDeCustoRepository repository;
    @Override
    public Optional<CentroDeCusto> centroDeCusto(Long id) {
        return repository.findById(id);
    @Override
    public Page<CentroDeCusto> centrosDeCusto(Pageable pagina) {
        return repository.departamentosPorDataDeAtualizacao(pagina);
    @Override
    public Optional<CentroDeCusto> buscaCentroDeCustoPeloNumero(String numero) {
        return repository.findByCentroDeCusto(numero);
    @Override
    public List<CentroDeCusto> buscaCentrosDeCustoDeUmaContaGerencial(Long idDaContaGerencial) {
        return repository.findByContasGerenciaisId(idDaContaGerencial);
    @Override
    public boolean verificaSeCentroDeCustoJahExiste(CentroDeCusto centroDeCusto) {
        String numeroDoCentroDeCusto = centroDeCusto.getCentroDeCusto();
        Long idDoCentroDeCusto = centroDeCusto.getId();
        Optional<CentroDeCusto> centroDeCustoOpt = repository.findByCentroDeCustoAndIdNotIn(numeroDoCentroDeCusto, idDoCentroDeCusto);
        if (centroDeCustoOpt.isPresent())
            return true;
        return false;
    @Override
    public CentroDeCusto criaCentroDeCusto(CentroDeCusto centroDeCusto) {
        return repository.save(centroDeCusto);
    @Override
    public CentroDeCusto atualizaCentroDeCusto(CentroDeCusto centroDeCusto) {
        return repository.save(centroDeCusto);
    @Override
    public boolean delataCentroDeCusto(Long id) {
        Optional<CentroDeCusto> centroDeCustoOpt = centroDeCusto(id);
        if (centroDeCustoOpt.isPresent()) {
            repository.delete(centroDeCustoOpt.get());
            return true;
        return false;

When I run the controller it seems that the test created for the Service class is impacting because both tests call the CentroDeCustoService object. How can I correctly configure test classes so that there are no more conflicts?

Error: Unable to register mock bean br.com.teste.reembolso.centrocusto.CentroDeCustoService expected a single matching bean to replace but found [centroDeCustoService, centroDeCustoServiceImpl]:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalStateException: Unable to register mock bean br.com.teste.reembolso.centrocusto.CentroDeCustoService expected a single matching bean to replace but found [centroDeCustoService, centroDeCustoServiceImpl]
    at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.getBeanName(MockitoPostProcessor.java:239)
    at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.registerMock(MockitoPostProcessor.java:184)
    at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.register(MockitoPostProcessor.java:174)
    at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:144)
    at org.springframework.boot.test.mock.mockito.MockitoPostProcessor.postProcessBeanFactory(MockitoPostProcessor.java:131)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:282)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:170)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:398)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:330)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:139)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
    ... 24 more

It looks like it's conflicting but I do not know how to solve it. can anybody help me?

I'm not sure you need to define additional CentroDeCustoService bean in test configuration. Try to remove it. – Bor Laze Feb 10, 2019 at 18:57 Please provide a code snippet that shows the productive registration of the CentroDeCustoService bean. Also, you should remove one of the tests (the one that is passing?) - because it seems unrelated, and is rather confusing. – oberlies Feb 11, 2019 at 10:19 Bor Laze and Oberlies. Thank you for your help. I followed Hermann Steidel's tip and it worked. – Thiago de Melo Fontana Feb 12, 2019 at 0:16 This is good, but this site is not only about helping the person that posted the question, but the questions should also help others with the same problem. In order to allow this, questions need to be concise (i.e. include all needed information and no unnecessary information). So please still update your question, as previously requested. Otherwise I and others will down-vote your question. – oberlies Feb 12, 2019 at 9:31 oberlies I added the implementation of CentroDeCustoService and CentroDeCustoServiceImpl and I got a better idea of the problem. Thanks for the sugestion. – Thiago de Melo Fontana Feb 12, 2019 at 12:32

You can use Qualifier in addition to @MockBean in case you have multiple beans of same type.

 @MockBean
 @Qualifier("centroDeCustoServiceImpl"
 private CentroDeCustoService service;

Refer MockBean java docs here:

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html

Also as per first comment to your question, you can avoid test configuration in the CentroDeCustoServiceImplTeste Unit Test. You can use a MockitoJunitRunner

I agree with others that you don't need the @TestConfiguration. Instead, just give a hint to your Spring test that you need your service class by using the @CntextConfiguration annotation.

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {CentroDeCustoServiceImpl.class})
public class CentroDeCustoServiceImplTeste {
    @Autowired
    private CentroDeCustoService centroDeCustoService;
                Hermann Steidel Obrigado mais uma vez. Funcionou kkkk. Você teria alguma indicação de curso no udemy ou artigo para que eu entenda melhor?
– Thiago de Melo Fontana
                Feb 12, 2019 at 0:15
                @Thiago de Melo Fontana  Lucky, I speak Spanish, I only had to translate 2 words. :) I don't have a comprehensive article to provide but for Udemy, this guy's courses seem to be pretty good: udemy.com/testing-spring-boot-beginner-to-guru  I took his general Spring Boot Rest course and it was pretty informative to get me going. I think Spring testing is tricky because there are so many ways to set them up. Plus, there are a bit of deprecated ways to do things that you have to be diligent when looking at articles.
– Hermann Steidel
                Feb 12, 2019 at 2:32

It's also possible to qualify mocked beans using only @MockBean annotation. I tested it with spring-boot 2.7.3.

Here is an example of declaration in tests:

@MockBean(name = "firstBean")
SomeBean bean1;
@MockBean(name = "secondBean")
SomeBean bean2;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.