在Spring Boot应用中做单元测试

举报
晴天X风 发表于 2018/03/14 20:27:06 2018/03/14
【摘要】 在Spring Boot应用中做单元测试文中用的Spring Boot是1.5.4版。1. 添加Maven依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope></dependency>按理来

在Spring Boot应用中做单元测试

文中用的Spring Boot是1.5.4版。

1. 添加Maven依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
</dependency>

按理来说只要添加上述依赖就好了。但如果你跟我一样,在跑测试时各种报错ClassNotFoundException net.minidev.xxx,请在pom文件中再加上如下两个依赖。


<dependency>
     <groupId>net.minidev</groupId>
     <artifactId>json-smart</artifactId>
     <version>2.2.1</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>net.minidev</groupId>
     <artifactId>asm</artifactId>
     <version>1.0.2</version>
     <scope>test</scope>
   </dependency>

遇到ClassNotFoundException 之类的问题,可参考我之前写的博客,一般不是因为所需的库重复,就是因为库不存在。可用mvn dependency:tree查看项目中库的依赖关系(直接在pom文件所在目录运行该命令就行了)。


2. 测试Service

@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentTest {

   @Autowired
   private StudentService studentService;

   @Test
   public void likeName() {
       assertArrayEquals(
               new Object[]{
                       studentService.likeName("小明2").size() > 0,
                       studentService.likeName("坏").size() > 0,
                       studentService.likeName("莉莉").size() > 0
                   },
               new Object[]{
                       true,
                       false,
                       true
                   }
       );
   }

}

第一个注解 @RunWith(SpringRunner.class) 告诉Junit运行使用Spring的测试支持,将运行spring的全部流程,再启动单元测试,也就是说会类似于spring的正常启动启动服务。

在JUnit中有很多个Runner,他们负责调用你的测试代码。如果只是普通的Java测试,该注解可省略,系统会自动使用默认Runner来运行你的测试类。

值得注意的是,网上很多教程用的是SpringJUnit4ClassRunner这个类,但这个类在1.5版本的Spring Boot已经被废弃了(1.4版本能用),不建议使用。

第二个注解@SpringBootTest表示使用带有Spring Boot支持的引导程序。该注解能在运行时配置Spring Boot的环境。

还可以用注解@ContextConfiguration(locations = "classpath:spring.xml")指定要加载的Spring配置文件,此处spring.xml文件放在了test的resource文件夹中。

网上有不少教程用的是@SpringApplicationConfiguration这个注解,该注解在1.4版的Spring Boot就被标记为过时了。

  1. 像平常测试一样,测试方法用@Test注解标注,测试类中也可以使用@Autowired来注入要测试的类的实例(因为测试环境是真实的Spring上下文)。

  2. 在最新版的JUnit中,assertEquals这类方法已经被废弃了,建议使用assertArrayEquals,可一次性输入多组测试数据。

2. 测试Controller

有两种方式,一是使用RestTemplate对象执行http请求,二是mock一个MVC环境。

其中注解@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)表示使用带有Spring Boot支持的引导程序,并使用默认的端口。该选项主要是为了在单元测试中通过 TestRestTemplate 对象模拟 http请求。

第一种:


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestExample2 {
   @LocalServerPort
   private int port;
   private URL base;

   @Autowired
   private TestRestTemplate template;

   @Before
   public void setUp() throws Exception {
       this.base = new URL("http://localhost:" + port + "/getUser/1");
   }

   @Test
   public void getHello() throws Exception {
       User user = userMapper.getById(1L);
       ResponseEntity<String> response = template.getForEntity(base.toString(),
           String.class);
       assertThat(response.getStatusCode, is(HttpStatus.OK))
       assertThat(response.getBody(), equalTo(user.toString()));
   }
}

第二种:


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class TestExample {
   @Autowired
   private MockMvc mvc;

   @Autowired
   private UserMapper userMapper;

   @Test
   public void testGetById() throws Exception {
       User user = userMapper.getById(1L);
       String uri = "/getUser/1";
       MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.get(uri).accept(MediaType.APPLICATION_JSON))
           .andReturn();
       int status = mvcResult.getResponse().getStatus();
       String content = mvcResult.getResponse().getContentAsString();
       assertTrue("错误,正确的返回值为200", status == 200);
       assertFalse("数据不一致", !user.toString().equals(content));
   }
}



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。