前言

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是认为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。本文将带大家介绍几款主流的单元测试使用方法,希望可以帮到大家。

公众号:「浅羽的IT小屋」

1、为什么要使用单元测试?

「好处:」

  • 可以使用单元测试来完成模块功能的一个测试

  • 使用单元测试可以更好的完成模块的回归测试

「在开发中一般要进行如下测试:」

  • 单元测试:一般情况下就是完成我们模块功能的一个检测

  • 回归测试:当我们开发好一个功能之后,这个功能是否会影响其他已经开发好的这个功能

  • 集成测试:简单的说就是项目开发完成的时候,这个所有功能是否完整,以及功能之间是否存在bug

  • 公测:进行公测

2、Junit的使用

「简介:」

  • Junit是单元测试框架工具,在项目开发中是经常用到的,利用Junit4进行单元测试非常简单方便,所以熟悉Junit是很有必要的

「主要用法:」

  @Before      //初始化数据用的  @BeforeClass  //初始化数据用的(只是执行一次)  @After       //对象销毁的时候用的  @AfterClass   //对象销毁的时候用的(只是执行一次)   @Test(expected=xxx.class、timeout=5000) (测试:期望出现某一类异常)

3、Hamcrest的使用(Junit的一个补充)

「使用原因:」

  • 使用过Junit的应该有体验:在实际开发中,一些基本的断言,如equal,null,true它们的可读性并不是很好。而且很多时候我们要比较对象、集合、Map等数据结构。这样我们要进行大段的字段获取再断言。或者干脆自己编写表达式并断言其结果

  • Junit4.4引入了Hamcrest框架,Hamcrest提供了一套匹配符,这些匹配符更接近自然语言,可读性高,更加灵活

  • 需求:假设说加法的上面,加上一个不为null的一个断言,这个时候就出现了两个断言,这时候你就需要写两次,有没有办法只写一次呢?有

  //使用这个Hamcrest来进行断言//        Assert.assertThat(result, IsNull.notNullValue());        // AllOf:所有的条件都要成立才表示校验成功        // AnyOf:一个条件校验成功那么才表示的是校验成功        // IsEqual:相等        // IsInstanceOf:这个就表示判定的是对象是否是某一个类的对象        // IsNot:不是某一个类的对象        // IsNull:判断空值        // StringEndWith:以什么结尾        // StringStartsWith:这个表示的是以什么开始        // SubStringMatcher:截取的字符串和谁匹配//        Assert.assertThat(result, AllOf.allOf(IsNull.notNullValue(), IsEqual.equalTo(30)));//       Assert.assertThat(result, AnyOf.anyOf(IsNull.notNullValue(), IsEqual.equalTo(30)));

「Unit4新断言-Hamcrest的常用方法:」

  • 字符相关匹配符

  1、equalTo:      assertThat(testedValue, equalTo(expectedValue));      断言被测的testedValue等于expectedValue,equalTo可以断言数值之间,字符串之间和对象之间是否相等,相当于Object的equals方法 2、equalToIgnoringCase:     assertThat(testedString, equalToIgnoringCase(expectedString));      断言被测的字符串testedString在忽略大小写的情况下等于expectedString 3、equalToIgnoringWhiteSpace:      assertThat(testedString, equalToIgnoringWhiteSpace(expectedString);      断言被测的字符串testedString在忽略头尾的任意个空格的情况下等于expectedString (注意:字符串中的空格不能被忽略) 4、containsString:      assertThat(testedString, containsString(subString) );      断言被测的字符串testedString包含子字符串subString 5、endsWith:      assertThat(testedString, endsWith(suffix));      断言被测的字符串testedString以子字符串suffix结尾 6、startsWith:      assertThat(testedString, startsWith(prefix));      断言被测的字符串testedString以子字符串prefix开始

  • 一般匹配符

  1、nullValue():      assertThat(object,nullValue());      断言被测object的值为null 2、notNullValue():      assertThat(object,notNullValue());      断言被测object的值不为null 3、is:      assertThat(testedString, is(equalTo(expectedValue)));      断言被测的object等于后面给出匹配表达式      1)is匹配符简写应用之一:           assertThat(testedValue, is(expectedValue));           is(equalTo(x))的简写,断言testedValue等于expectedValue      2)is匹配符简写应用之二:           assertThat(testedObject, is(Cheddar.class));           is(instanceOf(SomeClass.class))的简写,断言testedObject为Cheddar的实例 4、not:      assertThat(testedString, not(expectedString));      与is匹配符正好相反,断言被测的object不等于后面给出的object 5、allOf:      assertThat(testedNumber, allOf( greaterThan(8), lessThan(16) ) );      断言符合所有条件,相当于“与”(&&) 6、anyOf:      assertThat(testedNumber, anyOf( greaterThan(16), lessThan(8) ) );      断言符合条件之一,相当于“或”(||)

  • ‍‍‍‍数值相关匹配符

‍‍‍‍  1、closeTo:      assertThat(testedDouble, closeTo( 20.0, 0.5 ));      断言被测的浮点型数testedDouble在20.0-0.5 ~ 20.0+0.5范围之内 2、greaterThan:      assertThat(testedNumber, greaterThan(16.0));      断言被测的数值testedNumber大于16.0 3、lessThan:      assertThat(testedNumber, lessThan (16.0));      断言被测的数值testedNumber小于16.0 4、greaterThanOrEqualTo:      assertThat(testedNumber, greaterThanOrEqualTo (16.0));      断言被测的数值testedNumber大于等于16.0 5、lessThanOrEqualTo:      assertThat(testedNumber, lessThanOrEqualTo (16.0));      断言被测的testedNumber小于等于16.0

  • 集合相关匹配符

  1、hasEntry:      assertThat(mapObject, hasEntry("key", "value" ) );      断言被测的Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项 2、hasItem:      assertThat(iterableObject, hasItem (element));      表明被测的迭代对象iterableObject含有元素element项则测试通过 3、hasKey:      assertThat(mapObject, hasKey ("key"));      断言被测的Map对象mapObject含有键值“key” 4、hasValue:      assertThat(mapObject, hasValue(value));      断言被测的Map对象mapObject含有元素值value

4、Suit的使用

「需求:」

  • 现在有30个实体,每个DAO和每个Service都编写了测试用例。所以至少有60个测试类,当我们开发一个功能的时候,我们需要检测当前开发好的功能是否影响了其他已经开发好的功能,这个时候需要运行这60个测试用例,只有所有的测试用例都没有问题,才确定当前开发的功能对其他功能是没有影响的

  • 这个时候就需要运用Suit,Suit的作用就是可以一次性的运行多个测试用例

@RunWith(Suite.class)   //表示的是使用什么类来运行@Suite.SuiteClasses({TestCaltureB.class,TestCaltureA.class})  //这个表示的是要运行哪些类public class TestCaltureAB {}

5、Stub(装)的使用

「解决的问题:」

  • 假设两个人做开发,一个人做的是DAO,另外一个人做的是Service,现在的问题是DAO层还没有来得及开发,只是有约束规范(只有接口没有实现),现在是Service层需要测试,那怎么办呢?

  • Stub的思想就是:自己编写DAO的实现类使用Map集合来模拟数据库的数据以及访问的这个过程,就叫做Stub

「具体使用:」

  • 首先声明DAO的接口

public interface IUserDAO {    /**     * 通过id找用户     * @param userId     * @return     */    User getUserById(Serializable userId);}

  • 编写Service的实现类

public class UserService {    public IUserDAO userDAO=null;    public void setUserDAO(IUserDAO userDAO) {        this.userDAO = userDAO;    }    /**     * 通过id找用户     * @param userId     * @return     */    public User getUserById(Serializable userId){        User user=userDAO.getUserById(userId);        return user;    }}

  • 编写Stub的DAO的实现类

public class UserDAOStub implements IUserDAO{    //使用map集合来模拟我们的数据库    private Map<Integer,User> users=new HashMap<>();    public UserDAOStub() {        for (int i=0;i< 10;i++){            users.put(i+1,new User(i+1,i+1+"",i+1+""));        }    }    @Override    public User getUserById(Serializable userId) {        return users.get(userId);    }}

  • 编写测试的类

public class TestUserService {    private UserService userService=null;    private User exUser=null;    @Before    public void init(){        userService=new UserService();        exUser=new User();        //期望返回的的这个用户对象        exUser.setPassword("1");        exUser.setUserId(1);        exUser.setUserName("1");        UserDAOStub userDAOStub = new UserDAOStub();        userService.setUserDAO(userDAOStub);    }    @Test    public void testGetUserById(){        User user=userService.getUserById(1);        //接下来就进行断言了        Assert.assertEquals(exUser.getUserId(),user.getUserId());        Assert.assertEquals(exUser.getPassword(),user.getPassword());        Assert.assertEquals(exUser.getUserName(),user.getUserName());    }    @After    public void close(){        userService=null;    }}

6、dbunit的使用

「主要用途:」

  • dbunit是专门用来测试DAO层的,以后开发中DAO的测试就可以使用dbunit来进行

「使用流程:」

  • 备份所有的表

 private void backAllTable() throws SQLException, IOException, DataSetException {        //第一步:获取连接上的dataSet对象        IDataSet dataSet = conn.createDataSet();        //第二步:将数据进行备份        //使用属性来描述要备份的这个数据//      FlatXmlDataSet.write(dataSet,new FileOutputStream(new File("G:/allTable.xml")));        //使用节点来描述要备份的这个数据        XmlDataSet.write(dataSet, new FileOutputStream(new File("G:/allTable1.xml")));    }

  • 备份一张表

 /** * 备份一张表的数据 */private void backOneTable() throws DataSetException, IOException {    //创建一个查询的DataSet对象    QueryDataSet dataSet = new QueryDataSet(conn);    //第二步:添加要备份的表名    dataSet.addTable("t_user");    //第三步:进行备份    FlatXmlDataSet.write(dataSet, new FileOutputStream(new File("G:/allTable.xml")));}

  • 插入测试数据

/** * 插入准备好的数据到数据库 */private void insertDataTable() throws DatabaseUnitException, SQLException {    //获取插入数据的DataSet对象    IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(TestUserDAO.class.getClassLoader().getResourceAsStream("table.xml"))));    DatabaseOperation.CLEAN_INSERT.execute(conn, dataSet);}

  • 测试

@Testpublic void testFindUserById() throws SQLException, IOException, DatabaseUnitException {     backOneTable();     insertDataTable();    // 编写测试代码的地方    User acUser=userDAO.findUserById(78);  //实际返回的用户对象    //下一步:进行断言    Assert.assertEquals(exUser.getUserId(),acUser.getUserId());    Assert.assertEquals(exUser.getUserName(),acUser.getUserName());    Assert.assertEquals(exUser.getPassword(),acUser.getPassword());    //还原数据库的数据    resumeTable();}

  • 还原这个数据

/** * 还原数据库的数据 */private void resumeTable() throws IOException, DatabaseUnitException, SQLException {    //备份数据的DataSet对象    IDataSet dataSet=new FlatXmlDataSet(new InputSource(new FileInputStream(new File("G:/allTable.xml"))));    DatabaseOperation.CLEAN_INSERT.execute(conn,dataSet);}

  • 整体代码如下:

package com.qy.dbunit;import com.qy.utils.JdbcUtils;import org.apache.commons.dbutils.QueryRunner;import org.dbunit.DatabaseUnitException;import org.dbunit.database.AmbiguousTableNameException;import org.dbunit.database.DatabaseConnection;import org.dbunit.database.QueryDataSet;import org.dbunit.dataset.DataSetException;import org.dbunit.dataset.IDataSet;import org.dbunit.dataset.xml.FlatXmlDataSet;import org.dbunit.dataset.xml.FlatXmlProducer;import org.dbunit.dataset.xml.XmlDataSet;import org.dbunit.operation.DatabaseOperation;import org.junit.Assert;import org.junit.Before;import org.junit.Test;import org.xml.sax.InputSource;import java.io.*;import java.sql.SQLException;/** * @Auther: qianyu * @Date: 2020/11/17 10:02 * @Description: */public class TestUserDAO {    //维护的是用户的DAO的对象    private UserDAO userDAO=null;    //实例化dbunit中的这个数据库的连接    private DatabaseConnection conn = null;    //期望返回的用户对象值    private User exUser=null;    @Before    public void init() throws Exception {        conn = new DatabaseConnection(JdbcUtils.getConnection());        exUser=new User();        exUser.setUserId(78);        exUser.setUserName("78");        exUser.setPassword("78");        userDAO=new UserDAO();    }    /**     * 第一步:对数据库的数据进行备份     * 备份一张表的数据     * 备份整个数据库中的数据     * 第二步:插入提前准备好的测试数据     * 第三步:测试     * 第四步:将数据库的数据清空     * 第五步:还原数据库的数据     */    @Test    public void testFindUserById() throws SQLException, IOException, DatabaseUnitException {         backOneTable();         insertDataTable();        // 编写测试代码的地方        User acUser=userDAO.findUserById(78);  //实际返回的用户对象        //下一步:进行断言        Assert.assertEquals(exUser.getUserId(),acUser.getUserId());        Assert.assertEquals(exUser.getUserName(),acUser.getUserName());        Assert.assertEquals(exUser.getPassword(),acUser.getPassword());        //还原数据库的数据        resumeTable();    }    /**     * 还原数据库的数据     */    private void resumeTable() throws IOException, DatabaseUnitException, SQLException {        //备份数据的DataSet对象        IDataSet dataSet=new FlatXmlDataSet(new InputSource(new FileInputStream(new File("G:/allTable.xml"))));        DatabaseOperation.CLEAN_INSERT.execute(conn,dataSet);    }    /**     * 插入准备好的数据到数据库     */    private void insertDataTable() throws DatabaseUnitException, SQLException {        //获取插入数据的DataSet对象        IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(TestUserDAO.class.getClassLoader().getResourceAsStream("table.xml"))));        DatabaseOperation.CLEAN_INSERT.execute(conn, dataSet);    }    /**     * 备份数据库中所有表中的数据     */    private void backAllTable() throws SQLException, IOException, DataSetException {        //第一步:获取连接上的dataSet对象        IDataSet dataSet = conn.createDataSet();        //第二步:将数据进行备份        //使用属性来描述要备份的这个数据//      FlatXmlDataSet.write(dataSet,new FileOutputStream(new File("G:/allTable.xml")));        //使用节点来描述要备份的这个数据        XmlDataSet.write(dataSet, new FileOutputStream(new File("G:/allTable1.xml")));    }    /**     * 备份一张表的数据     */    private void backOneTable() throws DataSetException, IOException {        //创建一个查询的DataSet对象        QueryDataSet dataSet = new QueryDataSet(conn);        //第二步:添加要备份的表名        dataSet.addTable("t_user");        //第三步:进行备份        FlatXmlDataSet.write(dataSet, new FileOutputStream(new File("G:/allTable.xml")));    }}

  • 编写测试的基类

package com.qy.base;import org.apache.commons.dbutils.QueryRunner;import org.dbunit.DatabaseUnitException;import org.dbunit.database.AmbiguousTableNameException;import org.dbunit.database.DatabaseConnection;import org.dbunit.database.QueryDataSet;import org.dbunit.dataset.DataSetException;import org.dbunit.dataset.IDataSet;import org.dbunit.dataset.xml.FlatXmlDataSet;import org.dbunit.operation.DatabaseOperation;import org.xml.sax.InputSource;import java.io.*;import java.sql.Connection;import java.sql.SQLException;/** * @Auther: qianyu * @Date: 2020/11/17 10:58 * @Description: */public class AbstractDbunitTestCase implements Serializable{    //dbunit的这个连接    private DatabaseConnection conn=null;    //传入测试数据的dataSet对象    private IDataSet dataSetTest=null;    //创建一个临时文件    private File temFile=null;    public AbstractDbunitTestCase(Connection connection,IDataSet dataSetTest) throws DatabaseUnitException {        conn=new DatabaseConnection(connection);        this.dataSetTest=dataSetTest;    }    /**     * 备份多张表的数据     * @param tabNames     */    public void backManyTable(String ... tabNames) throws DataSetException, IOException {        QueryDataSet queryDataSet=new QueryDataSet(conn);        for (int i=0;i<tabNames.length;i++){            queryDataSet.addTable(tabNames[i]);        }        temFile=File.createTempFile("table",".xml");        //进行备份        FlatXmlDataSet.write(queryDataSet,new FileOutputStream(temFile));    }    /**     * 备份一张表     * @param tableName     */    public void backOneTable(String tableName) throws IOException, DataSetException {       backManyTable(tableName);    }    /**     * 插入测试数据     */    public void insertTestData() throws DatabaseUnitException, SQLException {        DatabaseOperation.CLEAN_INSERT.execute(conn,dataSetTest);    }    /**     * 还原这个表的数据     */    public void resumeTable() throws IOException, DatabaseUnitException, SQLException {        IDataSet dataSet=new FlatXmlDataSet(new InputSource(new FileInputStream(temFile)));        DatabaseOperation.CLEAN_INSERT.execute(conn,dataSet);    }}

  • 使用基类来完成测试

package com.qy.dbunit;import com.qy.base.AbstractDbunitTestCase;import com.qy.utils.JdbcUtils;import org.dbunit.dataset.xml.FlatXmlDataSet;import org.junit.After;import org.junit.Assert;import org.junit.Before;import org.junit.Test;import org.xml.sax.InputSource;import java.sql.SQLException;/** * @Auther: qianyu * @Date: 2020/11/17 11:12 * @Description: */public class TestUserDAO1 extends AbstractDbunitTestCase {    private UserDAO userDAO=null;    //期望返回的用户对象值    private User exUser=null;    public TestUserDAO1() throws Exception {        super(JdbcUtils.getConnection(),new FlatXmlDataSet(new InputSource(TestUserDAO1.class.getClassLoader().getResourceAsStream("table.xml"))));    }    @Before    public void init() throws Exception {        exUser=new User();        exUser.setUserId(78);        exUser.setUserName("78");        exUser.setPassword("79");        userDAO=new UserDAO();        backOneTable("t_user");        insertTestData();    }    @Test    public void testFindUserById() throws SQLException {        // 编写测试代码的地方        User acUser=userDAO.findUserById(78);  //实际返回的用户对象        //下一步:进行断言        Assert.assertEquals(exUser.getUserId(),acUser.getUserId());        Assert.assertEquals(exUser.getUserName(),acUser.getUserName());        Assert.assertEquals(exUser.getPassword(),acUser.getPassword());    }    @After    public void destory() throws Exception {       resumeTable();    }}

7、EasyMock的使用

「使用场景:」

dbunit是专门用来测试DAO层的EasyMock是专门用来测试Service层的DAO层的测试的重点:数据的准确性Service层测试的重点是DAO的调用次数、DAO层的调用的顺序EasyMocK的适用场景:就是当Service开发好之后 DAO层还没有来得及开发的时候 Service层需要测试

  • 第一个案例

public class TestUserService {    private UserService userService=null;    private User exUser=null;    @Before    public void init(){        userService=new UserService();        exUser=new User();        exUser.setUserId(1);        exUser.setUserName("浅羽");        exUser.setPassword("123");    }    /**     * 有返回值的情况     */    @Test    public void testFindUserById(){        //第一步:使用EasyMock生成接口的实现类        IUserDAO userDAO=EasyMock.createMock(IUserDAO.class);        //第二步:进行记录        //下面表示的意思是调用了上面对象的哪一个方法传递,某一个值的时候 希望的返回值是什么?        EasyMock.expect(userDAO.findUserById(1)).andReturn(exUser);        EasyMock.expect(userDAO.findUserById(1)).andReturn(exUser);        //第三步:进行replay(使能:使上面的设置生效)        EasyMock.replay(userDAO);        //第四步:进行设置        userService.setUserDAO(userDAO);        //第五步:进行测试        userService.findUserById(1);        //第六步:进行校验        EasyMock.verify(userDAO);    }    /**     * 没有返回值的情况     */    @Test    public void testSave(){        IUserDAO userDAO=EasyMock.createMock(IUserDAO.class);        //没有返回值的情况        //第一步:调用(记录中的调用)        userDAO.save();        //第二步:告诉他没有返回值        EasyMock.expectLastCall();        //第一步:调用(记录中的调用)        userDAO.save();        //第二步:告诉他没有返回值        EasyMock.expectLastCall();        //第一步:调用(记录中的调用)        userDAO.save();        //第二步:告诉他没有返回值        EasyMock.expectLastCall();        //使能        EasyMock.replay(userDAO);        //设置        userService.setUserDAO(userDAO);        //调用        userService.save();        //校验        EasyMock.verify(userDAO);    }    /**     * 测试有参数和没有参数混用的情况     * 注意:即时改变了顺序 只要你记录了都不会报错(非严格意义上的Mock)     *     */    @Test    public void testDelete(){        IUserDAO userDAO=EasyMock.createMock(IUserDAO.class);        //进行记录        //记录第一个调用        EasyMock.expect(userDAO.findUserById(1)).andReturn(exUser);        //记录第二个调用        userDAO.delete();        EasyMock.expectLastCall();        //第三个:使能        EasyMock.replay(userDAO);        //设置        userService.setUserDAO(userDAO);        //调用        userService.delete(1);        //校验        EasyMock.verify(userDAO);    }    /**     * 这个玩的是有严格顺序的Mock     * 严格意义上的Mock对调用的顺序都有联系     */    @Test    public void testDelete1(){        IUserDAO userDAO=EasyMock.createStrictMock(IUserDAO.class);        //进行记录        //记录第一个调用        EasyMock.expect(userDAO.findUserById(1)).andReturn(exUser);        //记录第二个调用        userDAO.delete();        EasyMock.expectLastCall();        //第三个:使能        EasyMock.replay(userDAO);        //设置        userService.setUserDAO(userDAO);        //调用        userService.delete(1);        //校验        EasyMock.verify(userDAO);    }}

  • 关于这个的高级应用

public class TestABService {    private ABService abService=null;    @Before    public void init(){        abService=new ABService();    }    /**     * 测试顺序的问题     */    @Test    public void testMM(){        //创建实现类        A a=EasyMock.createStrictMock(A.class);        B b=EasyMock.createStrictMock(B.class);        //进行记录        a.a();        EasyMock.expectLastCall();        a.b();        EasyMock.expectLastCall();        b.c();        EasyMock.expectLastCall();        b.d();        EasyMock.expectLastCall();        //使能        EasyMock.replay(a,b);        //设置        abService.setA(a);        abService.setB(b);        //调用        abService.mm();        //进行认证        EasyMock.verify(a,b);    }    @Test    public void testMMM(){        IMocksControl strictControl = EasyMock.createStrictControl();        A a=strictControl.createMock(A.class);        B b=strictControl.createMock(B.class);        //进行记录        a.a();        EasyMock.expectLastCall();        a.b();        EasyMock.expectLastCall();        b.c();        EasyMock.expectLastCall();        b.d();        EasyMock.expectLastCall();        //使能        strictControl.replay();        //设置        abService.setA(a);        abService.setB(b);        //调用        abService.mm();        //进行认证        strictControl.verify();    }    @Test    public void testMM1(){        IMocksControl strictControl = EasyMock.createStrictControl();        A a=strictControl.createMock(A.class);        B b=strictControl.createMock(B.class);        //进行记录        a.a();        EasyMock.expectLastCall();        a.b();        EasyMock.expectLastCall();        b.c();        EasyMock.expectLastCall();        b.d();        EasyMock.expectLastCall();        //使能        strictControl.replay();        //设置        abService.setA(a);        abService.setB(b);        //调用        abService.mm();        //进行认证        strictControl.verify();    }}

8、SpringTest的使用

「简介:」

  • 整合了Junit4框架,来做单元测试

「具体使用:」

  • 编写基类

@RunWith(SpringJUnit4Cla***unner.class)@ContextConfiguration(locations = {"classpath:bean-base.xml"})public class AbstractSpringTestCase {}

  • 测试

public class TestUserDAO extends AbstractSpringTestCase {    @Autowired   private UserDAO userDAO;    private User exUser=null;    @Before    public void init(){       exUser=new User(1,"浅羽","123");    }    @Test    public void testFindUserById(){         User acUser= userDAO.findUserById(1);         //断言        //下一步:进行断言        Assert.assertEquals(exUser.getUserId(),acUser.getUserId());        Assert.assertEquals(exUser.getUserName(),acUser.getUserName());        Assert.assertEquals(exUser.getPassword(),acUser.getPassword());    }}

结语

本篇关于单元测试的主流框架以及工具的介绍就先到这里结束了,后续会出更多关于单元测试系列文章,谢谢大家支持!

如果你觉得浅羽的文章对你有帮助的话,请在微信搜索并关注「 浅羽的IT小屋 」微信公众号,我会在这里分享一下计算机信息知识、理论技术、工具资源、软件介绍、后端开发、面试、工作感想以及一些生活随想等一系列文章。所见所领,皆是生活。慢慢来,努力一点,你我共同成长...

往期推荐

 

组件必知必会|那些年我们使用过的轮子—Filter和Proxy

【简历加分】hexo框架搭建个人博客站点,手把手教学。

ES开发指南|如何快速上手ElasticSearch

玩转Redis|学会这10点让你分分钟拿下Redis,满足你的一切疑问

吐血推荐|2万字总结Mac所有应用程序、软件工具和相关资料

超级详细|Linux系统下从0到1的玩法大全

IntelliJ IDEA热部署工具JRebel的使用教程

干货!MySQL优化原理分析及优化方案总结

点点点,一键三连都在这儿!

 

©著作权归作者所有:来自51CTO博客作者浅羽技术的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 【博客大赛】一篇文章了解CI/CD管道全流程
  2. 什么是敏捷开发?
  3. C# 排序算法
  4. 什么是黑盒测试和白盒测试、灰盒测试?
  5. 微信告警测试
  6. namp ***测试-安装篇
  7. 测试 python的魔术方法大全!记得收藏!!!
  8. docker部署tomcat(centos8测试)
  9. 冒烟测试怎么做?

随机推荐

  1. Android 知识总结
  2. android 实现button的背景改变
  3. 史上最全selector和shape使用方法 Androi
  4. Android剪切图片
  5. Android(安卓)Interface Definition Lang
  6. Android Studio 中编译JDK 版本配置
  7. phonegap与openlayers混搭在android上显
  8. 搭建IPC通信框架(RPC)
  9. 提供一些Android免费课程分享给大家
  10. 修改系统action bar字体大小、粗细、颜色