单元测试Bean注入时依赖不满足问题排查
Let's walk through the issues in your code and fix them one by one to get your test working correctly.
Key Problems in Your Original Code
Syntax Error in ComponentScan:
Your@ComponentScanannotation has a syntax mistake —basePackageClasses{com.tasks.ITest.class}is missing the equals sign and proper parentheses. This prevents Spring from scanning yourISynccomponent, so it never gets registered as a bean in the test context.Incorrect Context Configuration:
You've set@ContextConfiguration(classes = ITest.class), butITestis your test class, not a proper Spring configuration class. While it contains an inner configuration class, Spring might not correctly pick it up unless you explicitly reference the inner configuration.Missing Injection of the Class Under Test:
Your test class doesn't inject theISyncbean, so you can't actually test itssomeMethod()behavior. Even ifISyncwere registered, you wouldn't have an instance to work with.
Corrected Test Class Code
package com.tasks; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Profile; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @RunWith(SpringJUnit4ClassRunner.class) // Explicitly reference the inner configuration class @ContextConfiguration(classes = ITest.ITestConfiguration.class) @ActiveProfiles("test") public class ITest { @Autowired private IAccessor iAccessor1; // Mocked instance @Autowired private ISync iSync; // Class under test, injected with the mocked IAccessor @Test public void testRun() { // Execute the method we want to test iSync.someMethod(); // Verify that the mocked method was called (optional but recommended) verify(iAccessor1).someOtherMethod(); } @Configuration @Profile("test") // Fixed syntax for ComponentScan @ComponentScan(basePackageClasses = {com.tasks.ITest.class}) public static class ITestConfiguration { @Bean @Primary // Ensures this mock takes precedence over any other IAccessor beans public IAccessor iDataAccessor() { return mock(IAccessor.class); } } }
What We Fixed & Why
- ComponentScan Syntax: The corrected
@ComponentScan(basePackageClasses = {com.tasks.ITest.class})tells Spring to scan all components in thecom.taskspackage (including yourISyncbean). - Context Configuration: By pointing directly to
ITestConfiguration.class, we ensure Spring loads the exact configuration we need for the test, including the mockedIAccessorbean. - Injected ISync: Now we have an instance of the class under test, and Spring automatically injects the mocked
IAccessorinto it (thanks to@Primaryensuring the mock is used over any real implementations). - Added Mock Verification: I included a
verify()call to show how you can confirm the mocked method was invoked, which is a common practice in unit testing with Mockito.
Additional Checks
If you still run into issues, double-check:
- Your
ISyncclass has the@Componentannotation and lives in thecom.taskspackage (or a subpackage scanned byComponentScan). - The
ITestConfigurationis a static inner class — this is required for Spring to load it without instantiating the test class first. - Your
ActiveProfiles("test")is correctly applied, so only the test-specific configuration is loaded.
内容的提问来源于stack exchange,提问作者Bhavya Arora

