You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@WebMvcTest中排除Bean:主类依赖MyService时的测试简化问询

How to Avoid Adding @MockBean for MyService When Using @WebMvcTest

Problem Context

You have a main application class that implements CommandLineRunner and injects MyService:

@SpringBootApplication
public class MyMain implements CommandLineRunner {
    @Autowired
    private MyService myService;

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

    @Override
    public void run(String... args) {
        myService.doSomething();
    }
}

When testing your @RestController classes with @WebMvcTest, you're forced to add @MockBean private MyService myService; to every test class because Spring tries to initialize MyMain (and its dependencies) as part of the test context.


Solution 1: Separate CommandLineRunner Logic from the Main Class (Best Practice)

The cleanest approach is to move the startup logic into a dedicated CommandLineRunner bean instead of attaching it to your main application class. This keeps your main class lean and ensures @WebMvcTest doesn't pull in unnecessary dependencies.

Updated Main Class:

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

New Dedicated CommandLineRunner Bean:

@Component
public class MyStartupRunner implements CommandLineRunner {
    @Autowired
    private MyService myService;

    @Override
    public void run(String... args) {
        myService.doSomething();
    }
}

By default, @WebMvcTest doesn't load CommandLineRunner beans, so your controller tests won't require a mock for MyService anymore.


Solution 2: Exclude Unneeded Beans Directly in @WebMvcTest

If you prefer to keep the CommandLineRunner in your main class, you can use the excludeFilters attribute of @WebMvcTest to exclude either the main class itself or all CommandLineRunner implementations.

Option A: Exclude the Main Class

@WebMvcTest(
    controllers = YourRestController.class,
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ASSIGNABLE_TYPE,
        classes = MyMain.class
    )
)
public class YourRestControllerTest {
    // Your test code here, no need for @MockBean(MyService.class)
}

Option B: Exclude All CommandLineRunner Beans

@WebMvcTest(
    controllers = YourRestController.class,
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ASSIGNABLE_TYPE,
        classes = CommandLineRunner.class
    )
)
public class YourRestControllerTest {
    // Your test code here
}

Note: This will exclude all CommandLineRunner beans in your application, so use this only if you don't need any of them loaded during controller tests.


Why This Works

@WebMvcTest is designed to load only the beans required for testing Spring MVC controllers (like @RestController, @ControllerAdvice, etc.). However, since your main class is annotated with @SpringBootApplication, it's scanned by default, and its dependencies (like MyService) are pulled into the test context. By either separating the startup logic or excluding the problematic bean, you prevent that dependency from being required in your controller tests.

内容的提问来源于stack exchange,提问作者Iker Aguayo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:29:33