文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

当你在使用Spring框架开发企业级应用时,你的测试需求会就变得越来越复杂了,因此你就非常有必要去做集成测试。有时通过让Spring来管理bean会使你的测试变得相对简单,有时你可能需要测试你的Spring配置中的某一部分,而有时你则需要在你的测试中引入一个Mock组件。

Spring 和 JUnit 是一个强大的组合。你可以很轻易的引入自定义的Spring配置来满足你的测试场景的需求。

Spring 配置

我们可以有多种方式来创建Spring Beans。在这个例子中我将会使用Java配置。以下是我用来完成我们的集成测试的Spring配置类。

第 1 段(可获 1.48 积分)

ProductServiceTestConfig

请留意在类的顶部所使用的注解 @Configuration,这样就将该类指定为了Spring配置类。注解@Bean 会告诉 Spring 使用这个方法把一个Spring的bean加载到上下文中。Spring默认是使用方法名作为bean的名字。这个名字可以很轻易的通过使用 @Bean(name = "customBeanName") 代码将bean的名字传给bean的注解来完成修改。在这个配置类中,我定义了两个Spring bean,和我们在之前的单元测试样例和产品服务类的实现类中使用的测试存根类是一样的。你应该注意到了我并没有去管理将仓库bean注入到服务bean中。我们是通过Spring框架来管理依赖注入的。

第 2 段(可获 1.6 积分)
package guru.springframework.test.config;
 
import guru.springframework.repositories.ProductRepository;
import guru.springframework.repositories.ProductRepositoryTestStub;
import guru.springframework.services.ProductService;
import guru.springframework.services.ProductServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class ProductServiceTestConfig {
    @Bean
    ProductRepository productRepository(){
        return new ProductRepositoryTestStub();
    }
 
    @Bean
    ProductService productService(){
        return new ProductServiceImpl();
    }
}

 

第 3 段(可获 0.93 积分)

Spring 和JUnit 的配置

为了支持 Spring 和 JUnit,我们需要为我们的测试类添加两个新的注解。第一个注解就是 @RunWith(SpringJUnit4ClassRunner.class) 。这个注解是有JUnit团队提供的,是用来让JUnit能够扩展支持一个自定义的测试运行器类。在这个注解内部,我们传递了SpringJUnit4ClassRunner.class 类作为参数,它是由Spring框架所提供的。这个自定义的测试运行器使得Spring的上下文起作用。你的测试类实际上也变成了一个Spring Bean,并且被 Spring 上下文所管理。我们需要用到的第二个注解就是 @ContextConfiguration,这允许我们为Spring上下文指定配置。这个注释的配置是非常通用的。随着你的应用的复杂程度的增加,你的配置也会不断的增加。对于我们现在的例子来说,我们的需求并不复杂。我只引入了一个配置类到 Spring 的上下文中。我们可以非常简单的通过使用classes属性将类名传给这个注解,就像这样:@ContextConfiguration(classes = {ProductServiceTestConfig.class})。通过使用这两个注解,我当我运行整个单元测试时,Spring的上下文就会被启动,然后那些我们在配置中指定的bean也就可以在我们的测试中使用了。

第 4 段(可获 2.78 积分)

JUnit 测试

按照惯例,我的集成测试类命名使用“IT”结尾。习惯上,你应该让你的单元测试的命名以‘Test’ 或 ‘Tests’结尾,而集成测试的命名应该以‘IT’结尾。这些不会影响JUnit怎么运行测试。但是当你在后续使用像Maven之类的工具进行构建和使用Jenkins之类的持续构建服务器进行部署和报告时,会有多多少少的影响的。

ProductServiceImplIT

下面这个类跟我们上面看到的那个单元测试类看起来一样,但是这是一个集成测试类,是使用Spring来管理依赖注入的。在这里我们将这个测试类加上我们之前所讨论过的那两个注解。由于这个类现在是由Spring所管理的,我就可以使用@Autowired注解来把我们的服务bean注入到测试中。 这个bean是一个Spring Bean,由Spring来配置和管理。因此它就可以为我们注入我们在测试配置类中所指定的repository对象。

第 5 段(可获 2.13 积分)
package guru.springframework.services;
 
import guru.springframework.domain.Product;
import guru.springframework.test.config.ProductServiceTestConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
import static org.junit.Assert.assertEquals;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ProductServiceTestConfig.class})
public class ProductServiceImplIT {
    private ProductService productService;
 
    @Autowired
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }
 
    @Test
    public void testGetProduct(){
        Product product = productService.getProduct(1L);
        assertEquals(product.getDescription(), "This is a test product");
    }
}

 

第 6 段(可获 1.46 积分)

文章评论