有事没事领个红包

springboot集成spock进行单元测试

1. springboot2.X 集成 spock-spring 进行单元测试,在 pom 中添加 spock 依赖

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

        <!-- https://mvnrepository.com/artifact/org.spockframework/spock-spring -->
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>1.3-groovy-2.5</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.spockframework/spock-core -->
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.3-groovy-2.5</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all -->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.5.8</version>
            <type>pom</type>
            <scope>test</scope>
        </dependency>

添加两个plugin用于编译 groovy 代码和使用spock测试的类名规则

<!-- Mandatory plugins for using Spock -->
            <plugin>
                <!-- The gmavenplus plugin is used to compile Groovy code. To learn more about this plugin,
                visit https://github.com/groovy/GMavenPlus/wiki -->
                <groupId>org.codehaus.gmavenplus</groupId>
                <artifactId>gmavenplus-plugin</artifactId>
                <version>1.11.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compileTests</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

 

2 在项目中新加如下测试目录结构

 

 

 标记 groovy 目录为 test source root

3 spock 中的代码块和junit对应关系

 

 

 4 常用的模式有

初始化/执行/期望
given:
when:
then:


期望/数据表
expect:
where:

4.1 数据表中每个测试都是相互独立的,都是specification class该类型的一个具体实例,每条都会执行 setup() cleanup()方法,

4.2 常用的指令有

@Shared //共享
@Timeout //超时时间
@Ignore //忽略该方法
@IgnoreRest //忽略其他方法
@FailsWith //有些问题暂时没有解决
@Unroll // 每个循环独立报告

 5 测试 json 请求

//controller 方法
@Slf4j
@RestController
public class StudentController {

    @RequestMapping(path = "/student", method = RequestMethod.POST)
    public Student addStudent(@RequestBody Student student) {
        if (student.getName() == null) {
            throw new RuntimeException("name is null");
        }
        log.info("request msg:[{}]", student);
        Random random = new Random();
        student.setId(random.nextInt(1000));
        log.info("response msg:[{}]", student);
        return student;
    }
}


//Student model
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private Integer id;
    private String name;
    private Integer age;
}

编写单元测试方法

package com.huitong.controller


import com.huitong.model.Student
import com.huitong.util.JsonObjectUtil
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import spock.lang.Specification

import javax.servlet.http.HttpServletResponse

/**
 * <p>
 * </p>
 * author pczhao <br/>
 * date  2020/11/15 11:39
 */

@ActiveProfiles("dev")
@SpringBootTest
@AutoConfigureMockMvc
class StudentControllerTest extends Specification {

    @Autowired
    private MockMvc mockMvc;

    def "this is my first web test"() {
        given:
        def stu = Student.builder().name("allen").age(23).build();
        when:
        def res = mockMvc.perform(
                MockMvcRequestBuilders.post("/student")
                        .contentType(MediaType.APPLICATION_JSON).content(JsonObjectUtil.convertObjectToJson(stu)))
                .andReturn()
        then:
        res.response.status == HttpServletResponse.SC_OK


    }

}

 

6 测试文件上传

//controller 文件
@Slf4j
@RestController
public class FileController {

    @RequestMapping(path = "/upload/file", method = RequestMethod.POST)
    public String uploadFile(@RequestParam("username") String username, @RequestParam("file") MultipartFile file) {
        String desDir = "D:\\logs\\service-demo\\";
        String desFilename = desDir + file.getOriginalFilename();
        try {
            file.transferTo(new File(desFilename));
            return username + " upload file success, " + desFilename;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return username + " upload file failure, " + desFilename;
    }
}

对应的groovy测试文件

package com.huitong.controller

import org.apache.commons.io.FileUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.mock.web.MockMultipartFile
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder
import spock.lang.Specification

import javax.servlet.http.HttpServletResponse

/**
 * <p>
 * </p>
 * author pczhao <br/>
 * date  2020/11/15 13:48
 */

@ActiveProfiles("dev")
@SpringBootTest
@AutoConfigureMockMvc
class FileControllerTest extends Specification {

    @Autowired
    private MockMvc mockMvc;

    def "test upload file controller"() {
        given:
        String username = "allen"
        MockMultipartFile srcFile = new MockMultipartFile("file", "test.pptx", "text/plain", FileUtils.readFileToByteArray(new File("C:\\Users\\Administrator.DESKTOP-D5RT07E\\Desktop\\test.pptx")))
        when:
        def result = mockMvc.perform(new MockMultipartHttpServletRequestBuilder("/upload/file").file(srcFile).param("username", username)).andReturn()
        println(result)
        then:
        result.response.status == HttpServletResponse.SC_OK
    }
}

 

 

 

参考资料:

http://spockframework.org/spock/docs/1.3/all_in_one.html#_using_code_with_code_for_expectations

 

posted @ 2020-11-12 19:26  crazyCodeLove  阅读(4110)  评论(2编辑  收藏  举报