单元测试的问题

本文探讨了单元测试的重要性,包括黑盒与白盒测试的区别,以及如何通过Junit、Hamcrest、Suite、Stub、Dbunit、Spring测试和EasyMock进行单元测试。详细介绍了每个框架的使用场景和步骤,如Suite用于批量运行测试用例,Stub解决DAO层未实现时的测试问题,EasyMock则专注于业务逻辑层测试。
摘要由CSDN通过智能技术生成

单元测试的问题

1、为什么要写单元测试

1、为了进行模块功能的测试

​ 黑盒子测试:不管这个方法的实现是怎么回事的 只需要管 这个方法整体测试出来是否满足我们的 要求

​ 白盒子测试:简单的说 我们在测试这个方法的时候 不光要测试整体的功能是否满足要求 还要对当前方法里面所有的测试分支编写我们的测试用例

​ 单元测试 :一般情况下黑盒子测试

2、可以进行回归测试

​ 当我们编写好一个方法的时候 这个方法是否影响了 其他已经编写好的方法呢? 那么这个时候 只需要运行一下 所有的测试用例 如果所有的测试用例 都没有报错 那么就说明你编写的方法没有影响其他方法

2、Junit的使用

public class TestCalture {

    private Calture calture;


    //初始化这个实例

    @Before             //这个注解的作用就是在测试用例执行之前进行对象实例化的
    // 由 @before修饰的方法  一般情况下用来进行测试的对象以及数据的初始化
    public void init(){
       calture=new Calture();
    }


    /**
     * 测试加法
     */
    @Test
    public void testAdd(){
        int addResult = calture.add(1, 1);
        //执行了结果之后 :判断这个结果和预期结果是否一致
        //判断结果正确与否  那么 叫断言
        assertEquals(2,addResult);

    }


    /**
     * 测试这个处罚是否正确
     * expected:希望返回某一类的异常
     * timeout:测试用例执行的超时时间
     */
    @Test(expected = ArithmeticException.class,timeout = 5000)
    public void testCf(){
        int cfResult = calture.cf(10, 0);
        assertNotNull(cfResult);
        assertEquals(5,cfResult);
    }


    @After
    public void destroy(){
        calture=null;
    }
}

3、Hamcreast的使用

需求:执行了这个cf方法执行 我需要进行多个判断

​ 这读个判断 只需要一个满足条件就成立了…

这个hamcreat简单的说就是对原来的Junit的功能的增强

比如:同时成立

​ 一个成立就成立呀

​ 判断null呀 等等 都有封装

@Test(/*expected = ArithmeticException.class,timeout = 5000*/)
    public void testCf(){
        int cfResult = calture.cf(10, 1);

        //下面的两个判断  只要其中一个成立了  那么 这个断言就成立了
        // 我在断言的时候 不能单独写成一个一个断言  我需要 写到一起怎么办呢?

        /*assertNotNull(cfResult);
        assertEquals(5,cfResult);*/

        assertThat(cfResult, AnyOf.anyOf(IsNull.notNullValue(), IsEqual.equalTo(5)));

        
        /**
         * AnyOf.anyOf:一个成立那么就成立
         *
         * AllOf.allOf():所有成立才成立
         *
         * IsNull.notNullValue():不能是null值
         *
         * IsNull.nullValue():必须是null值
         *
         * IsInstanceOf.instanceOf():必须是某一个类的实例
         *
         * IsAnything:这个表示的是对象其中一个
         *
         * IsNot:不能是某一个数据  或者某一个对象
         */

    }

4、Suite的使用

场景:我要一起运行多个测试用例

当我们开发好一个功能之后 如果需要手动的去云星宇一个一个测试用例 那么 就太浪费时间了 那么怎么办呢?

在这种场景下 suite就应运而生了…

4.1、准备第一个测试用例
public class TestCaltuteA {
   

    private Calture calture=null;

    @Before
    public void init(){
   
        calture=new Calture();
    }
    
    @Test
    public void testAdd(){
   
        int addResult = calture.add(1, 1);
        Assert.assertEquals(2,addResult);
    }
}

4.2、准备第二个测试用例
public class TestCaltuteB {
   
    private Calture calture=null;
    @Before
    public void init(){
   
        calture=new Calture();
    }

    @Test
    public void testCf(){
   
        int addResult = calture.cf(10, 2);
        Assert.assertEquals(5,addResult);
    }    
}
4.3、准备测试
@RunWith(Suite.class)
@Suite.SuiteClasses({
   TestCaltuteA.class,TestCaltuteB.class})
public class TestCaltureAB {
   
}

5、stub的使用

stub:装逼的装

有这样一种场景:我们分层做开发 A做的是业务逻辑层 B做的是DAO层 那么这个时候 当B刚写玩约束规范(DAO接口) 就请假了 结果A把业务逻辑层写完了 要写测试用例了 咋办呢? 那么这个时候A就想到了一种解决这个问题的方式:stub这种思想

适用场景:DAO有规范但是没有实现的情况下 Service要做测试

5.1、准备DAO接口
public interface IUserDAO {
   


    /**
     * 通过id找到用户
     * @param id
     * @return
     */
    User findUserById(int id);

}
5.2、准备业务逻辑层的调用
public class UserService {
   
    private IUserDAO userDAO;
    public void setUserDAO(IUserDAO userDAO) {
   
        this.userDAO = userDAO;
    }


    /**
     * 测试的方法
     * @return
     */
    public User findUserById(int id){
   
        //中间经历了无数个步骤
        //....
        //....
        return userDAO.findUserById(id);
    }
}
5.3、准备测试类
public class TestUserService {

    private UserService userService;

    private User exUser;

    @Before
    public void init(){
        userService=new UserService();

        userService.setUserDAO(new UserDAOStub());
        exUser=new User(1,"小波波:1","密码:1");
    }

    /**
     * 测试通过id找用户的这个方法
     */
    @Test
    public void testFindUserById(){
        User useResult = userService.findUserById(1);
        //接下来进行断言
        Assert.assertEquals(exUser.getId(),useResult.getId());
        Assert.assertEquals(exUser.getUserName(),useResult.getUserName());
        Assert.assertEquals(exUser.getPassword(),useResult.getPassword());
    }


}

5.4、准备stub的DAO实现
public class UserDAOStub implements IUserDAO {
   
    private Map<Integer,User> userMap=new HashMap<>();
    public UserDAOStub(){
   
        for (int i = 1; i <10 ; i++) {
   
              userMap.put(i,new User(i,"小波波:"+i,"密码:"+i));
        }
    }

    @Override
    public User findUserById(int id) {
   
        return userMap.get(id);
    }
}

6、dbunit的使用

dbunit是用来干嘛的呢? 简单的说 dbunit的主要的功能就是用来做DAO层的测试

不是 dbutils(DAO层的解决方案) 、dbunit(专门用来测试DAO层的框架)

6.1、导包
         <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>

        <!--DAO层测试的这个框架包-->
        <dependency>
            <groupId>org.dbunit</groupId>
            <artifactId>dbunit</artifactId>
            <version>2.5.3</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.22</version>
        </dependency>
6.2、编写DAO代码
public class UserDAO {
   
    /**
     * 通过id找用户
     * @param id
     * @return
     */
    public User findUserById(int id) throws SQLException {
   
        User user = queryRunner().query("select * from t_user where id=?", new BeanHandler<User>(User.class), id);
        return user;
    }

}
6.3、编写数据库访问的帮助类
public class JdbcUtils {
   

    private static DruidDataSource dataSource=null;

    static{
   
        dataSource=new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///cd200101");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
    }

    /**
     * 这个是获取咋们的操作数据库的对象
     * @return
     */
    public static QueryRunner queryRunner(){
   
        return new QueryRunner(dataSource);
    }

    /**
     * 获取咋们的连接
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
   
        return dataSource.getConnection();
    }
}
6.4、编写咋们的基类
public class AbstractDbunitTestCase {
   

    private DatabaseConnection connection;
    private File tempFile;
    private IDataSet testDataSet;    //测试数据的DataSet对象

    public AbstractDbunitTestCase(Connection conn,String testFileName) throws DatabaseUnitException {
   
        this.connection=new DatabaseConnection(conn);
        InputStream inputStream =AbstractDbunitTestCase.class.getClassLoader().getResourceAsStream(testFileName);
        testDataSet=new FlatXmlDataSet(new FlatXmlProducer(new InputSource(inputStream)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值