利用Mockito模拟DB

简介:

前两篇文章的主要内容是:为了给执行测试,如何建立数据库表和导入初始数据。这里我们将学习如何利用Mockito框架和一些注解模拟(mock)Repository实例,从而使得测试用例不依赖外部的数据库服务。

我们需要创建一个Spring Boot配置类,在该类中定义用于测试的Spring Bean;我们通过注解指示Spring Boot何时加载测试配置类以及何时执行该类中的代码。在改配置类中,我们将使用Mockito框架创建一些带预定义方法的mock对象,Spring Boot在执行测试用例之前会将这些对象织入。

How Do

  • 首先创建一个注解用于标识仅用于测试的配置类,可以按照如下方法修改BookPubApplication类。可以看出,关键语句@ComponentScan(excludeFilters = @ComponentScan.Filter(UsedForTesting.class))表示:程序正式运行时不扫描@UsedForTesting修饰的类。
@Configuration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = @ComponentScan.Filter(UsedForTesting.class))
@EnableScheduling
public class BookPubApplication {
    public static void main(String[] args) {
        SpringApplication.run(BookPubApplication.class, args);
    }
    @Bean
    public StartupRunner schedulerRunner() {
        return new StartupRunner();
    }
}

@interface UsedForTesting {}
  • 在src/test/java/com/test/bookpub目录下创建TestMockBeansConfig文件,内容是:
package com.test.bookpub;

import com.test.bookpub.repository.PublisherRepository;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
@UsedForTesting
public class TestMockBeansConfig {
    @Bean
    @Primary
    public PublisherRepository createMockPublisherRepository() {
        return Mockito.mock(PublisherRepository.class);
    }
}
  • 新建一个测试类——PublisherRepositoryTests,主要是因为BookPubApplicationTest中的内容太多太乱了(在实际项目中我们会严格限制每个测试类中的内容)。
package com.test.bookpub;
import com.test.bookpub.repository.PublisherRepository;
import org.junit.After;import org.junit.Before;import org.junit.Test;
import org.junit.runner.RunWith;import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
        BookPubApplication.class,
        TestMockBeansConfig.class
})
@IntegrationTest
public class PublisherRepositoryTests {
    @Autowired
    private PublisherRepository repository;

    @Before
    public void setupPublisherRepositoryMock() {
        Mockito.when(repository.count())
                .thenReturn(1L);
    }
    @Test
    public void publishersExist() {
        assertEquals(1, repository.count());
    }

    @After
    public void resetPublisherRepositoryMock() {
        Mockito.reset(repository);
    }
}

分析

OK,分析下刚刚发生了什么。首先,我们从对BookPubApplication.java的修改开始:

  • @SpringBootApplication被三个注解替换:@Configuration, @EnableAutoConfiguration@ComponentScan(excludeFilters = @ComponentScan.Filter(UsedForTesting.class)),这么做的原因是可以给@ComponentScan注解增加excludeFilters属性,通过这个属性,我们提示Spring Boot在正式运行时忽略被@UsedForTesting修饰的类。
  • @UsedForTesting注解定义在BookPubApplication.java文件中,用于修饰TestMockBeansConfig类。

接下来看看在TestMockBeansConfig中的操作,

  • @Configuration注解说明这是一个配置类,该类含有应用程序上下文,如果被其他配置文件引入,则该类中定义的Spring Bean应该加入到已经创建的应用上下文。
  • 修饰createMOckPublisherRepository方法的注解@Primary表示:如果在织入的时候发现有多个PublisherRepository的Spring Bean,则让Spring Boot优先使用该方法返回的Spring Bean。在应用程序启动时,Spring Boot根据@RepositoryRestResource注解,已经生成一个PublisherRepository的实例,但是这里我们希望应用程序不使用这个真实的实例,而使用Mockito框架模拟出的PublisherRepository实例。

最后看下我们的测试用例,主要关注setupPublisherRepositoryMock方法和resetPublisherRepositoryMock方法:

  • setupPublisherRepositoryMock方法被@Before注解修饰,表示在测试用例运行之前被调用,在这个方法中我们配置了mock对象的行为:如果收到repository.count()调用,则返回1。Mockito框架提供了很多DSL形式的语句,可以用于定义这些容易理解的规则。

  • resetPublisherRepositoryMock方法被@After注解修饰,在测试用例执行过后调用,用于清楚之前对repository的设置。



相关文章
|
SQL IDE NoSQL
tp5源码解析--Db操作
在TP5的框架使用过程中,Db类是一定会接触到的,上手不难,但若想随心所欲的用,还是需要了解一番。用了千次,却没看过一次源码,学习源码,起码对TP5这个框架使用更加得心应手,毕竟技术服务于业务,能够写出更简介、更方便、更有效的业务代码,本身就是一件身心愉悦的事儿;
153 0
|
关系型数据库 Java 数据库连接
Hibernate连接DB2的问题(已解决)
折腾半个月了,这个问题一直没有得到解决。 我有两个web应用,它们使用同一个数据库,通过hibernate连接。应用A向数据库里插入、修改和删除数据,应用B读取数据展现给用户。在Mysql里使用一切正常,现在决定使用DB2数据库,理论上讲只要在DB2里建一个空数据库,然后修改hibernate.properties就可以了。
1401 0
|
关系型数据库 MySQL 数据库
EntityFrameWork连接多Db配置
  如题所示,EF作为微软主推的ORM工具,最新版本已经是7,说明有很多人在使用它做项目。在使用过程中,可能会连接不同的数据库,本文介绍的是连接SqlServer,MySql和SQLite三种,并且可以互相切换。
1522 0
|
测试技术 数据库 Java
|
存储 SQL 测试技术
谈一下我们是怎么做数据库单元测试(Database Unit Test)的
作者水平有限,如有错误或纰漏,请指出,谢谢。 背景介绍 最近在团队在做release之前的regression,把各个feature分支merge回master之后发现DB的单元测试出现了20多个失败的test cases。
1861 0
|
SQL 关系型数据库 数据库
db2相关问题及解决方法
DB2相关问题及解决方法: 一、DB2中的代码页(codepage)问题。 DB2备份时发生过代码页错误的问题,修改代码页后备份正常,但创建数据库时又发生代码页的错误。这是DB2服务器使用的代码页配置和客户端使用的代码页配置不同造成的(注:DB2服务器的代码页配置是独立的,用代码页不同的客户端操作服务器就会产生错误。
1177 0
|
存储 关系型数据库 数据库
【DB2学习文档之五】设置DB2环境
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.级别对应 • Environment variables at the operating system level • The DB2 profile registry variable...
981 0
|
SQL Java 关系型数据库
Log4Jdbc测试例子。
我与的log4jdbc的测试例子,在例子运行过程中需要log4j-1.2.15.jar,log4jdbc4-1.2alpha1.jar,slf4j-api-1.5.5.jar,slf4j-log4j12-1.5.5.jar,同时需要数据库相应版本的JDBC驱动程序。
735 0
|
存储 关系型数据库
自己开发DB2工具 (11)
目前公司内部开发后台这块主要用的工具还是QC 4.8 ,但是QC4.8有个问题就是在导出一些特别长的存储过程的时候会出错发生截断现象。
772 0