我如何JUnit测试一个Spring自动装配的构造函数?

前端之家收集整理的这篇文章主要介绍了我如何JUnit测试一个Spring自动装配的构造函数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我在线搜索了很多,我找不到使用自动装配构造函数进行单元测试的示例.我使用Spring自动属性文件中的值自动装入我的应用程序.我想单元测试MyApp.java的start方法,但我有一个自动装配的构造函数,所以我不知道如何实例化MyApp.没有自动装配属性,我在单元测试中这样做:

  1. @Test
  2. public void testStart() {
  3. try{
  4. MyApp myApp = new MyApp();
  5. myApp.start();
  6. }
  7. catch (Exception e){
  8. fail("Error thrown")
  9. }
  10. }

我不想模拟自动装配,因为我需要从属性文件获取值并使事情进一步复杂化,我通过注释配置所有内容.我没有spring.xml,application-context.xml或web.xml文件.那么我该如何实例化/测试MyApp的start方法呢?我尝试添加@RunWith(SpringJUnit4ClassRunner.class)并自动装载MyApp myApp,但是它会导致错误,无法通过在测试类上实现ApplicationContextAware来加载未修复的应用程序上下文.

这是MyApp.java

  1. @Component
  2. public class MyApp {
  3. private static ApplicationContext applicationContext;
  4. private static MyAppProperties myAppProperties;
  5. //Obtain the values from the app.properties file
  6. @Autowired
  7. MyApp(MyAppProperties myAppProps){
  8. myAppProperties = myAppProps;
  9. }
  10. public static void main(String[] args) throws Exception {
  11. // Instantiate the application context for use by the other classes
  12. applicationContext = new AnnotationConfigApplicationContext("com.my.company");
  13. start();
  14. }
  15. /**
  16. * Start the Jetty server and configure the servlets
  17. *
  18. * @throws Exception
  19. */
  20. public static void start() throws Exception {
  21. // Create Embedded Jetty server
  22. jettyServer = new Server();
  23. // Configure Jetty so that it stops at JVM shutdown phase
  24. jettyServer.setStopAtShutdown(true);
  25. jettyServer.setStopTimeout(7_000);
  26. // Create a list to hold all of the handlers
  27. final HandlerList handlerList = new HandlerList();
  28. // Configure for Http
  29. HttpConfiguration http_config = new HttpConfiguration();
  30. http_config.setSecureScheme("https");
  31. http_config.setSecurePort(myAppProperties.getHTTP_SECURE_PORT());
  32. ....
  33. }
  34. }

这是我的app.properties文件

  1. # Spring Configuration for My application
  2. #properties for the embedded jetty server
  3. http_server_port=12345

这是MyAppProperties.java

  1. @Component
  2. public class MyAppProperties implements ApplicationContextAware {
  3. private ApplicationContext applicationContext;
  4. //List of values from the properties files to be autowired
  5. private int HTTP_SERVER_PORT;
  6. ...
  7. @Autowired
  8. public MyAppProperties( @Value("${http_server_port}") int http_server_port,...){
  9. this.HTTP_SERVER_PORT = http_server_port;
  10. }
  11. /**
  12. * @return the applicationContext
  13. */
  14. public ApplicationContext getApplicationContext() {
  15. return applicationContext;
  16. }
  17. /**
  18. * @param applicationContext
  19. * the applicationContext to set
  20. */
  21. @Override
  22. public void setApplicationContext(ApplicationContext applicationContext) {
  23. this.applicationContext = applicationContext;
  24. }
  25. /**
  26. * @param name
  27. * the name to set
  28. */
  29. public void setHTTP_SERVER_PORT(String name) {
  30. JETTY_SERVER_NAME = name;
  31. }
  32. /**
  33. * @return the httpServerPort
  34. */
  35. public int getHTTP_SERVER_PORT() {
  36. return HTTP_SERVER_PORT;
  37. }
  38. }

这是MyAppTest.java

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class MyAppTest implements ApplicationContextAware{
  3. private ApplicationContext applicationContext;
  4. @Override
  5. public void setApplicationContext(ApplicationContext appContext) {
  6. applicationContext = appContext;
  7. }
  8. @Autowired
  9. private MyApp myapp;
  10. @Test
  11. public void testStart(){
  12. try {
  13. if(myapp != null){
  14. myapp.start();
  15. }
  16. else{
  17. fail("myapp is null");
  18. }
  19. } catch (Exception e) {
  20. fail("Error thrown");
  21. e.printStackTrace();
  22. }
  23. }
  24. }

更新:这是我的配置类

  1. @Configuration
  2. @Component
  3. public class ApplicationConfig implements ApplicationContextAware {
  4. private final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class);
  5. private ApplicationContext applicationContext;
  6. /**
  7. * @return the applicationContext
  8. */
  9. public ApplicationContext getApplicationContext() {
  10. LOGGER.debug("Getting Application Context",applicationContext);
  11. return applicationContext;
  12. }
  13. /**
  14. * @param applicationContext
  15. * the applicationContext to set
  16. */
  17. @Override
  18. public void setApplicationContext(ApplicationContext applicationContext) {
  19. this.applicationContext = applicationContext;
  20. }
  21. // Needed for @Value
  22. /**
  23. * Property sources placeholder configurer.
  24. *
  25. * @return the property sources placeholder configurer
  26. */
  27. @Bean
  28. public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
  29. PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
  30. propertyPlaceholderConfigurer.setLocation(new ClassPathResource("app.properties"));
  31. return propertyPlaceholderConfigurer;
  32. }
  33. ...
  34. }
最佳答案
我们可以使用jmockito框架来模拟对象.

使用@InjectMocks通过Mockito进行依赖注入
你还有@InjectMocks注释,它试图根据类型进行构造函数,方法或字段依赖注入.以下代码是Javadoc中稍微修改过的示例.

  1. // Mockito can construct this class via constructor
  2. public class ArticleManager {
  3. ArticleManager(ArticleCalculator calculator,ArticleDatabase database) {
  4. }
  5. }
  6. // Mockito can also perform method injection
  7. public class ArticleManager {
  8. ArticleManager() { }
  9. void setDatabase(ArticleDatabase database) { }
  10. void setCalculator(ArticleCalculator calculator) { }
  11. }
  12. // Mockito can also perform field injection
  13. public class ArticleManager {
  14. private ArticleDatabase database;
  15. private ArticleCalculator calculator;
  16. }

以下是单元测试类.

  1. @RunWith(MockitoJUnitRunner.class)
  2. public class ArticleManagerTest {
  3. @Mock private ArticleCalculator calculator;
  4. @Mock private ArticleDatabase database;
  5. @Spy private UserProvider userProvider = new ConsumerUserProvider();
  6. // creates instance of ArticleManager
  7. // and performs constructor injection on it
  8. @InjectMocks private ArticleManager manager;
  9. @Test public void shouldDoSomething() {
  10. // assume that ArticleManager has a method called initialize which calls a method
  11. // addListener with an instance of ArticleListener
  12. manager.initialize();
  13. // validate that addListener was called
  14. verify(database).addListener(any(ArticleListener.class));
  15. }

}

确保您使用的是@RunWith(MockitoJUnitRunner.class)
有关更多信息,请参阅http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/InjectMocks.html.

猜你在找的Spring相关文章