简体   繁体   中英

Spring Unit test

When I start my application as Spring Boot application, ServiceEndpointConfig gets autowired properly. But when I run as Junit test, I get the following exception. I am using application.yml file and different profiles.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyServiceContextConfig.class, 
loader = SpringApplicationContextLoader.class) 
@ActiveProfiles({"unit", "statsd-none"})
public class MyServiceTest
{
}

@Configuration
public class MyServiceContextConfig {

    @Bean
    public MyService myServiceImpl(){
        return new MyServiceImpl();
    }
}

@Configuration
@Component
@EnableConfigurationProperties
@ComponentScan("com.myservice")
@Import({ServiceEndpointConfig.class})
public class MyServiceImpl implements MyService {

   @Autowired
   ServiceEndpointConfig serviceEndpointConfig;

}

@Configuration
@Component
@ConfigurationProperties(prefix="service")
public class ServiceEndpointConfig
{
}

Error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': 
Unsatisfied dependency expressed through field 'serviceEndpointConfig': No qualifying bean of type [com.myservice.config.ServiceEndpointConfig] found 

You're handling MyServiceImpl inconsistently: On the one hand, you're using scanning annotations, and on the other, you're explicitly creating an @Bean in a configuration class. The import directive is only processed when Spring picks MyServiceImpl up via scanning; otherwise, it's not treated as a configuration.

Your relationships between the classes are tangled up; the whole point of dependency injection is that MyServiceImpl should say what sort of thing it needs but not create it itself. This organization is no better than manually creating dependencies internally.

Instead,

  • eliminate the @Configuration and @Import directives from MyServiceImpl ,
  • use constructor injection on MyServiceImpl , and
  • change your test configuration to include all the necessary configuration classes.

With constructor injection, you may be able to bypass the Spring context entirely and run this as an actual unit test by simply creating a new MyServiceImpl(testServiceConfig) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM