Spock 使用教程 (二) 之与 Springboot 的整合

本贴最后更新于 1623 天前,其中的信息可能已经事过景迁

一、需求

1、启动测试类的时候只加载相应的 java 类,而不是启动整个项目
2、可以 mock 相关的 java 类以及方法的返回值

二、实现

2.1 、准备

要测试的 java 类为 UserServiceImpl,依赖了 UserMapper 代码如下:

public class UserServiceImpl implements UserService {

    @Autowired
    private  UserMapper userMapper;
    @Override
    //根据用户ID查询用户信息
    public User selectUserById(Integer userId){
        User user=userMapper.seleteUserById(userId);
        return user;
    }
    //修改用户信息
    @Override
    public void updateUser(User user){
        userMapper.updateById(user);
    }
    //删除用户信息
    @Override
    public void deleteUserById(Integer userId){
        userMapper.deleteUserById(userId);
    }
    //添加用户信息
    public void inserUser(User user){
        user.setregisterTime(new Date());
        userMapper.inserUser(user);
    }
}

2.2 测试代码如下:

@SpringBootTest
@ContextConfiguration(classes = UserServiceImpl.class)
@WebAppConfiguration
class UserInfoSpec extends Specification {
    @Autowired
    UserServiceImpl userService
    @SpringBean
    UserMapper userMapper = Mock()
    def setup() {}
    @Unroll
    def "testSelectUserById"() {
        given:
        def user = new User(userId: userId, userName: userName, passWord: passWord);
        userMapper.seleteUserById(userId) >> user
        expect:
        userService.selectUserById(userId) == user
        where:
        userId   | userName | passWord
        1234567L | xiaoming | 123456
        12309756 | xiaohong | 4321134
    }
}

三、代码讲解

3.1、@SpringBootTest

@SpringBootTest 注解告诉 SpringBoot 去寻找一个主配置类(例如带有 @SpringBootApplication 的配置类),并使用它来启动 Spring 应用程序上下文。只用这个注解也是可以的,会自动注入所有的 bean,我们不用 mock,缺点是当我们只测试一个类,也会加载完全无关的类,启动慢,浪费时间。

3.2、@ContextConfiguration

@ContextConfiguration loads an ApplicationContext for Spring integration test. @ContextConfiguration can load ApplicationContext using XML resource or the JavaConfig annotated with @Configuration. The @ContextConfiguration annotation can also load a component annotated with @Component, @Service, @Repository etc. We can also load classes annotated with javax.inject
简而言之就是使用 ContextConfiguration 注解可以只加载你想要加载的 bean,不用加载所有的 bean
官网用法链接

3.3、 @SpringBean

spock 支持的注解
官方文档解释:
Registers mock/stub/spy as a spring bean in the test context.To use @SpringBean you have to use a strongly typed field def or Object won’t work. You also need to directly assign the Mock / Stub / Spy to the field using the standard Spock syntax. You can even use the initializer blocks to define common behavior, however they are only picked up once they are attached to the Specification . @SpringBean definitions can replace existing Beans in your ApplicationContext.
下一篇文章会解释 mock、stub 和 spy
3.4、@Unroll
spock 支持的注解和 where 一起用,相当于创建了多个 test
3.5、

def user = new User(userId: userId, userName: userName, passWord: passWord);

spock 支持的 bean 的创建,也可以把参数直接换成常量,也支持 java 中的 bean 的实例化,个人觉得 spock 支持的比较好用,没有传的参数默认是 null.

userMapper.seleteUserById(userId) >> user

相当于创建 mock 一个方法的返回值,当我们传的参数为 userId 时,userMapper.seleteUserById 方法的返回值是 user,也可用_表示任何参数;

userMapper.seleteUserById(_) >> user
userMapper.seleteUserById(null) >> { throw new InternalError("ouch") }
userMapper.seleteUserById(!null)>>user

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...