4

I have a simple controller e.g.

@Controller
public class FooController
{
    @Autowired
    private BarService barService;

    @RequestMapping(value = "/foo", method = RequestMethod.GET)
    public String displayFoo()
    {
        return "foo";
    }
}

When I want to do a @WebMvcTest, I have to create a great number of @MockBeans to prevent a NoSuchBeanDefinitionException.

@RunWith(SpringRunner.class)
@WebMvcTest
@Import(WebSecurityConfig.class)
public class FooControllerTest
{
    @MockBean ...
    @MockBean ...
    @MockBean ...
    ...
    ...
}

Does this mean that BarService is somehow creating a chain of dependencies? (it has some dependencies but some @MockBeans appear completely unrelated).

The problem is, is that each @WebMvcTest I add for different controllers also requires the same @MockBeans.

Should I be using an annotation like @TestConfiguration to specify all the @MockBeans for the DRY principal?

  • If FooController only depends on BarService as your code shows, you should only need one mock bean for BarService. A mock bean doesn't have any dependency: it's a mock. – JB Nizet Mar 03 '18 at 14:01

3 Answers3

4

I looked at this again, and found you can pass the controller name to @WebMvcTest e.g. @WebMvcTest(FooController.class).

Specifies the controllers to test. May be left blank if all {@code @Controller} beans should be added to the application context.

1

As Hal8k said, if you don't specify a controller like @WebMvcTest(YourController.class), it will try to load all @Controller components. And @Import(WebSecurityConfig.class) also try to inject components in WebSecurityConfig.class.

Refer : https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4

Min Hyoung Hong
  • 1,102
  • 9
  • 13
0

This could happen when the bean scanning configuration is faulty or excessive.

In my case, I was still getting the error despite having specified the controller to test in @WebMvcTest(FooController.class).

I eventually realised it was due to the @ComponentScan of my application being needlessly cluttered up. My Application.java was something like this:

@SpringBootApplication
@ComponentScan({"fr.nevechris.projectname","fr.nevechris.projectname.otherpackage"})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

I removed the @ComponentScan entirely and the issue was solved.

If your @ComponentScan is good or not specified, try searching for other places in your project where configuration is done (eg @Configuration tag).

Chris Neve
  • 2,164
  • 2
  • 20
  • 33