The following code taken from the doc doesn't work as expected:

@RunWith(SpringRunner.class)
@WebMvcTest(TestController.class)
public class TestControllerTest {

    @MockBean
    private TestValidator testValidator;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void test() throws Exception {
        // no-opts
    });
}

... where's the mocked bean is:

@Component
public class TestValidator implements Validator {

    @Autowired
    private TestRepository testRepository;
    ...
}

during test startup it fails:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testController': Unsatisfied dependency expressed through field 'testValidator': Error creating bean with name 'com.example.TestValidator#0': Unsatisfied dependency expressed through field 'categoryRepository': No qualifying bean of type [com.example.TestRepository] found for dependency [com.example.TestRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. 

Java: 1.8.0_65 Spring Boot: 1.4.0.RELEASE & 1.4.1-BUILD-SNAPSHOT Maven: 3.3.3

Test project on GitHub

Comment From: wilkinsona

Thanks for the sample.

I don't think this has anything to do with @MockBean. The problem is that you're using @WebMvcTest but with a bean that autowires a Data JPA repository. Data JPA repositories aren't created when using @WebMvcTest.

Rather than mocking TestValidator, is there any reason why you can't mock Validator instead? You'd have to change the injection point in TestController. Alternatively, you can also avoid the problem by using constructor injection instead of field injection.

I guess we could look at disabling autowiring for beans created using @MockBean so that if it's a mock created from a class (rather than from an interface) no attempt is made to inject anything into it.

Comment From: WildDev

@wilkinsona ,

I don't think this has anything to do with @MockBean. The problem is that you're using @WebMvcTest but with a bean that autowires a Data JPA repository. Data JPA repositories aren't created when using `@WebMvcTest.

yes, but there is any controller interacts with the database either via service layer or whatever else. In order to test a controller it is necessary to mock its dependencies anyway. Data JPA repository shouldn't be autowired at all since it is just a dependency of the dummy object.

I will try your suggestion but IMAO, the @MockBean annotation should behave the same like Mockito's @Mock annotation does - it just makes a dummy object without any nested dependencies resolved.

Comment From: wilkinsona

Will try your suggestion but IMAO, the @MockBean annotation should to behave exactly like Mockito's @Mock does

In terms of how the mock is created, that's exactly what @MockBean does. However, we have to do more than @Mock – the mock has to be added to the application context so that it can be injected into other components. It's the fact that's it's a bean in the application context that means that an attempt is made to inject its fields which is what's causing the problem you've reported.

Comment From: WildDev

@wilkinsona , then it behaves rather like a stub that not always sufficient for the testing

Comment From: snicoll

Looks like a rephrased clone of #6658

Comment From: WildDev

@snicoll , has nothing with the #6658 at all

Comment From: snicoll

Yeah, @wilkinsona just told me. The complaints look alike :)

Comment From: SingleShot

I experience this same problem when the unit under test's dependencies are plain old Spring beans that themselves have autowired dependencies. If the unit's dependencies are interfaces, no problem, they mock fine. But if classes, the mocking does not work completely and requires the dependencies of the dependency to be wired in.

The "workaround" for this is to provide @MockBeans for dependencies of the dependency, and dependencies of the dependency's dependencies and so on down, which is pretty ugly. Another is to only use interfaces for your dependencies - which I prefer - but you don't always have that luxury when the dependency is not in your control. Of course, I could wrap it in my own interface but that's extra code that I wouldn't need if @MockBean behaved like Mockito class mocking from the standpoint of not needing to provide dependencies to the mock.

For me - someone trying to port a legacy (and very messy) Spring app over to several Spring Boot apps - getting this fixed is important. (Oh I see it is no longer waiting for triage - thanks!)

Comment From: snicoll

Fixed in https://github.com/spring-projects/spring-boot/commit/0e00a49dcc246893fcaf1c7a0497fac6dcbc7454

Comment From: StasKolodyuk

I experience the same issue for @SpyBean. However, the @MockBean works correctly in 1.4.1.RELEASE

Comment From: wilkinsona

@StasKolodyuk That's to be expected. Unlike a mock, a spy is a wrapper around a "proper" bean. For the bean that's being spied upon to work properly it needs to have its dependencies injected.

Comment From: StasKolodyuk

@wilkinsona That makes sense, thank you!

Comment From: danilobalarini

Just to say that i got rid of this bug by removing the @ComponentScan from my @SpringBootApplication - Application.class

There is no need for it anymore (using spring-boot 1.5.2)

Comment From: stahloss

For my project setup @MockBean is still not working as it should. We have multiple @Configurations that are imported by our @SpringBootApplication annotated class. These @Configuration classes each have their own @Import or @ImportResource. When using @MockBean we get all kinds of wiring issues, but when we mock or stub implement our rest controller manually, things are fine as is our application in general. I am able to get @MockBean working, but only when I remove the explicit @Imports, but of course this breaks everything else.

Comment From: snicoll

@D0rmouse this issue was closed almost 2 years ago. If you have a usage question please ask on StackOverflow with a link to a minimal sample that reproduces the behaviour you're experiencing. The description you shared is vague and we won't be able to help you effectively without more details. If you believe you've found a bug in Spring Boot, please create a separate issue with a link to a minimal sample.

Comment From: stahloss

@snicoll Thanks for your response. I don't need usage help, just giving you a heads-up that @MockBean has wiring issues in the described situation. Stub implementing our business service interface wired by our rest controller does not have this issue. I'll see if I can create a minimal setup to reproduce this and create a separate issue.