当前位置: 首页 > 知识库问答 >
问题:

如何测试Spring自动连接构造函数?

云镜
2023-03-14

我在网上做了很多搜索,但找不到一个使用自动连接构造函数进行单元测试的例子。我正在使用Spring将属性文件中的值自动关联到我的应用程序。我想对我的应用程序进行单元测试。java的start方法,但我有一个自动连接的构造函数,所以我不知道如何实例化MyApp。在没有自动连线属性的情况下,我在单元测试中这样做:

@Test
public void testStart() {
  try{
   MyApp myApp = new MyApp();
   myApp.start();
   }
   catch (Exception e){
     fail("Error thrown")
   }
}

我不想模拟自动布线,因为我需要从属性文件中获取值,并且为了使事情更加复杂,我正在通过注释配置一切。我没有Spring。xml,应用程序上下文。xml或web。xml文件。那么,我该如何实例化/测试MyApp的start方法呢?添加application-aware到application-myclassrunner时,我没有尝试在@junit4中实现application-aware-myclassrunner和application-aware-myclassrunner来修复这个错误。

这是我的应用。JAVA

@Component
public class MyApp {

    private static ApplicationContext applicationContext;
    private static MyAppProperties myAppProperties;

    //Obtain the values from the app.properties file
    @Autowired
    MyApp(MyAppProperties myAppProps){
        myAppProperties = myAppProps;
    }

    public static void main(String[] args) throws Exception {
     // Instantiate the application context for use by the other classes
     applicationContext = new AnnotationConfigApplicationContext("com.my.company");

     start();
    }

    /**
     * Start the Jetty server and configure the servlets
     * 
     * @throws Exception
     */
    public static void start() throws Exception {
        // Create Embedded Jetty server
        jettyServer = new Server();

        // Configure Jetty so that it stops at JVM shutdown phase
        jettyServer.setStopAtShutdown(true);
        jettyServer.setStopTimeout(7_000);

        // Create a list to hold all of the handlers
        final HandlerList handlerList = new HandlerList();

        // Configure for Http
        HttpConfiguration http_config = new HttpConfiguration();
        http_config.setSecureScheme("https");
        http_config.setSecurePort(myAppProperties.getHTTP_SECURE_PORT());
    ....
    }
}

这是我的应用程序。属性文件

# Spring Configuration for My application

#properties for the embedded jetty server
http_server_port=12345

这里是MyAppProperties。JAVA

@Component
public class MyAppProperties implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    //List of values from the properties files to be autowired
    private int HTTP_SERVER_PORT;
    ...

    @Autowired
    public MyAppProperties( @Value("${http_server_port}") int http_server_port, ...){
        this.HTTP_SERVER_PORT = http_server_port;
    }

    /**
     * @return the applicationContext
     */
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * @param applicationContext
     *            the applicationContext to set
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setHTTP_SERVER_PORT(String name) {
        JETTY_SERVER_NAME = name;
    }

    /**
     * @return the httpServerPort
     */
    public int getHTTP_SERVER_PORT() {
        return HTTP_SERVER_PORT;
    }
}

这是我的应用测试。JAVA

@RunWith(SpringJUnit4ClassRunner.class)
public class MyAppTest implements ApplicationContextAware{

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext appContext) {
        applicationContext = appContext;    
    }

    @Autowired
    private MyApp myapp;

    @Test
    public void testStart(){
    try {
        if(myapp != null){
            myapp.start();
        }
        else{
            fail("myapp is null");
        }
    } catch (Exception e) {
        fail("Error thrown");
        e.printStackTrace();
    } 
    }
}

更新:这是我的配置类

@Configuration
@Component
public class ApplicationConfig implements ApplicationContextAware {

    private final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class);
    private ApplicationContext applicationContext;

    /**
     * @return the applicationContext
     */
    public ApplicationContext getApplicationContext() {
        LOGGER.debug("Getting Application Context", applicationContext);
        return applicationContext;
    }

    /**
     * @param applicationContext
     *            the applicationContext to set
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    // Needed for @Value
    /**
     * Property sources placeholder configurer.
     *
     * @return the property sources placeholder configurer
     */
    @Bean
    public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer() {
        PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
        propertyPlaceholderConfigurer.setLocation(new ClassPathResource("app.properties"));
        return propertyPlaceholderConfigurer;
    }
    ...
}

共有1个答案

史默
2023-03-14

我们可以使用jmockito框架模拟对象。

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

// Mockito can construct this class via constructor
public class ArticleManager {
         ArticleManager(ArticleCalculator calculator, ArticleDatabase database) {
        }
}

// Mockito can also perform  method injection
public class ArticleManager {
        ArticleManager() {  }
        void setDatabase(ArticleDatabase database) { }
        void setCalculator(ArticleCalculator calculator) { }
}

// Mockito can also perform  field injection
public class ArticleManager {

    private ArticleDatabase database;
    private ArticleCalculator calculator;
}

以下是单元测试课程。

@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest  {
   @Mock private ArticleCalculator calculator;
   @Mock private ArticleDatabase database;
   @Spy private UserProvider userProvider = new ConsumerUserProvider();

   // creates instance of ArticleManager
   // and performs constructor injection on it
   @InjectMocks private ArticleManager manager;

   @Test public void shouldDoSomething() {
           // assume that ArticleManager has a method called initialize which calls a method
           // addListener with an instance of ArticleListener
           manager.initialize();

       // validate that addListener was called
           verify(database).addListener(any(ArticleListener.class));
   }

}

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

 类似资料:
  • 我正在从事一个Spring Boot项目,在尝试自动连接服务时遇到了一些问题。这是我当前的代码: 构造函数参数和在运行时是已知的,因此我无法硬编码它们或将它们存储在配置文件中。 这是通过反射从实例化的地方(将根据用户交互而更改。在这个例子中,它将是: 当试图构建项目时,我得到以下错误: 我相信问题在于我没有将作为构造函数参数传递,但是由于我的项目的性质,这些服务不能作为参数传递,因为它们将根据通过

  • 我想知道以下解决方案之间的区别是什么,为什么使用解决方案2?有什么好处吗? 解决方案一: 解决方案2:

  • 例如,我有一个这样的课; 我要做的是为模拟的构造函数编写单元测试。 如果是静态的,那么这将很容易,因为我可以使用然后调用构造函数。 有人知道有什么办法吗?

  • 问题内容: 我有一堂课要添加单元测试。该类具有多个构造函数,这些构造函数采用不同的类型并将其转换为规范形式,然后可以将其转换为其他类型。 实际上,它接受并转换为其他两种类型。 我正在尝试找出最合适的方法来测试这些构造函数。 应该有一个针对每个构造函数的测试和输出类型: 这导致许多不同的测试。如您所见,我正在努力命名它们。 应该有多个断言: 这有多个断言,这使我感到不舒服。它还正在测试getStri

  • 2014-12-20 15:35:52错误TestContextManager:334-允许TestExecutionListener[org.springframework.test.context.support.dependencyInjectionTestExecutionListener@5af97850]准备测试实例[com.amsb.bariz.base.test.usertest@

  • 我在我的spring boot应用(spring Hibernate/Data/JPA/Web)中有这个类: pkg实体: pkg存储库: pkg服务: 如果我不创建任何控制器,所有工作,但如果我创建一个控制器: pkg控制器: 我得到这个错误(ConfigController中的autowired ConfigService错误): 第一个问题是:我已经注释了@Transaction的BaseS