前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android开发之逻辑单元测试

Android开发之逻辑单元测试

作者头像
大大大大大先生
发布于 2018-09-04 07:21:49
发布于 2018-09-04 07:21:49
1.5K00
代码可运行
举报
运行总次数:0
代码可运行

单元测试的必要性

  • 完整,规范的单元测试有利于提升程序的“自动化”验证
  • 降低后期程序的维护成本
  • 高覆盖率的单元测试在很大程度上能提前发现一些潜在的bug
  • 编写单元测试的过程中可以帮助程序模块化重构,一个耦合性非常高的程序是无法针对他编写完善的单元测试的
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void connectImpl(String domain, String ip, int port) {
        callOnStartConnect(domain,ip,port);
        try {
            socket = createSocket();
            String hostname = domain;
            if (!"".equals(ip) && ip != null) {
                hostname = ip;
            }
            //String hostname = DomainManager.getHostName(domain, ip);
            long start = System.currentTimeMillis();
            InetSocketAddress inetSocketAddress = createInetSocketAddress(hostname, port);
            long end = System.currentTimeMillis();
            long inetTime = end - start;
            InetAddress inetAddress = inetSocketAddress.getAddress();
            if (inetAddress != null) {
                ip = inetAddress.getHostAddress();
            }
            long startConn = System.currentTimeMillis();
            socket.connect(inetSocketAddress, connectTimeout);
            long endConn = System.currentTimeMillis();
            long connectTime = endConn - startConn;
            LogUtil.i(TAG, "connect时间间隔(ms):" + connectTime);
            inputStream = socket.getInputStream();
            outputStream = socket.getOutputStream();
            TCPConnection.this.domain = domain;
            TCPConnection.this.ip = ip;
            TCPConnection.this.port = port;
            callOnConnected(domain,ip,port,inetTime,connectTime);

            LogUtil.i(TAG, "connect to server success,domain:" + domain + ",port:" + port);
        } catch (IOException e) {
            LogUtil.w(TAG, e);//注意:Log工具直接把UnknownHostException返回""

            callOnConnectFailed(domain, ip, port,e);
            return;
        }
        startReadData();
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private InetSocketAddress createInetSocketAddress(String hostname, int port) {
        long start = System.currentTimeMillis();
        InetSocketAddress inetSocketAddress = new InetSocketAddress(hostname, port);
        long end = System.currentTimeMillis();
        long inetTime = end - start;
        LogUtil.i(TAG, "inetSocketAddress时间间隔(ms):" + inetTime);
        InetAddress inetAddress = inetSocketAddress.getAddress();
        String localDnsIp = null;
        if (inetAddress != null) {
            localDnsIp = inetAddress.getHostAddress();
        }
        LogUtil.i(TAG, "local dns ip:" + localDnsIp);
        return inetSocketAddress;
    }

以上createInetSocketAddress方法就是我在编写单元测试的时候单独抽离出来的方法,一方面我需要mock一个InetSocketAddress来满足测试需求,另一方面,单独抽离一个createInetSocketAddress方法从代码上看也是必要的,让方法职责更加单一,如果把createInetSocketAddress的实现直接耦合到connectImpl方法中,那么connectImpl的代码除了连接tcp的逻辑外还有创建InetSocketAddress的逻辑,这样就比较混乱,而且方法体也变长

Android单元测试的分类

纯代码逻辑的单元测试,也就是Java单元测试,在test目录下
  • 目前我们项目中用junit + powermock这一套单元测试框架,选择powermock的一个重要的原因就是:现如今比较流行的Mock工具如jMock 、EasyMock 、Mockito等都有一个共同的缺点:不能mock静态、final、私有方法等。而PowerMock能够完美的弥补以上三个Mock工具的不足,具体详细信息可以参考这篇文章:http://blog.csdn.net/jackiehff/article/details/14000779
什么是mock?为什么要mock?
  • mock就是模拟,在代码逻辑测试中,有时候我们需要某一个方法返回我们指定的值,这样才能跑我们预测的代码逻辑,从而通过验证执行结果的正确性来反映该代码逻辑是否有问题,比如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
     * 开始处理同步通知任务
     *
     * @param syncKey 消息版本号
     */
    private synchronized void executeTask(final long imAccountId, final long syncKey) {
        Queue<Runnable> queue = getTaskQueue(imAccountId);
        queue.offer(new Runnable() {
            @Override
            public void run() {
                handleInformResponse(imAccountId, syncKey, new OnNextCallback() {
                    @Override
                    public void onNext() {
                        LogUtil.d(TAG, "sync request on next");
                        scheduleNext(imAccountId);
                    }
                });
            }
        });
        if (isLocked(imAccountId)) {
            LogUtil.w(TAG, "the imAccountId [" + imAccountId + "] is locked.");
            return;
        }
        lock(imAccountId);
        scheduleNext(imAccountId);
        LogUtil.d(TAG, "execute the inform task");
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
     * 检测一个会话的同步通知处理是否被锁定
     *
     * @param imAccountId im帐户系统id
     * @return true表示已该帐户有正在处理中的同步通知,反之
     */
    private boolean isLocked(long imAccountId) {
        synchronized (imformLockMap) {
            LockStatus lockStatus = imformLockMap.get(imAccountId);
            if (lockStatus == null) {
                return false;
            }
            if (System.currentTimeMillis() - lockStatus.lockTimestamp >= 20000 && lockStatus.locked) {
                lockStatus.locked = false;
                imformLockMap.put(imAccountId, lockStatus);
            }
            return lockStatus.locked;
        }
    }

上面在测试executeTask方法的时候,isLocked返回true和false分别执行的是不通的分支逻辑,因此需要通过控制isLocked的返回值来分别覆盖到这两个逻辑执行流程,mock方法isLocked并返回指定的值,首先需要创建一个经过mock的对象,只有mock的对象才能mock对象中的所有方法或者变量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
syncInformHandler = PowerMockito.mock(SyncInformHandler.class);
PowerMockito.doReturn(false).when(syncInformHandler, "isLocked", Mockito.anyLong());
// or
PowerMockito.doReturn(true).when(syncInformHandler, "isLocked", Mockito.anyLong());
  • mock后的对象有什么区别?
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HeartConfig heartConfig = PowerMockito.mock(HeartConfig.class);
// heartConfig = new HeartConfig();

如上heartConfig被mock后生成的对象,它与new出来对象的区别在于,new出来的heartConfig对象,当你调用getMinHeart()方法的时候会真正的去执行这个方法,而且对象被new出来之后,对象中的一些值已经被初始化了,例如对象中的变量的赋值,静态代码块,构造函数都已经执行;但是对于mock出来的heartConfig对象,它的一切都是空的,调用getMinHeart()也不会真正的去执行这个方法,而是执行powermock框架的代理方法,heartConfig对象中的全局变量的复制都是空的,比如说:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private int test = 2;

如果对象new出来之后,那么test的值一定就是2,而对于mock出来的对象,test的值是0

powermock几种常用的mock方式
  • 如果使用powermock,需要在类加入注释:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(PowerMockRunner.class)
public class HeartStateContextTest {
// ...
}
  • 如果需要mock对象中的private,final,static,native方法或者final class,使用PowerMockito.whenNew,需要给类加入注解,注解里加入你要mock的class:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@PrepareForTest({SyncInformHandler.class, ManagerFactory.class, RequestEntityFactory.class, AccountStore.class})
public class SyncInformHandlerTest {
// ...
}
  • mock常规的public方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HeartConfig heartConfig = PowerMockito.mock(HeartConfig.class);
PowerMockito.doReturn(120).when(heartConfig).getMinHeart();
PowerMockito.doReturn(580).when(heartConfig).getMaxHeart();
PowerMockito.doReturn(60).when(heartConfig).getStep();
PowerMockito.doReturn(3).when(heartConfig).getMaxFailedCount();
  • mock类中的private方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
syncInformHandler = PowerMockito.mock(SyncInformHandler.class);
PowerMockito.doReturn(false).when(syncInformHandler, "canDoSync", Mockito.anyLong(), Mockito.anyLong());
  • mock类中的静态方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PowerMockito.mockStatic(ManagerFactory.class);
managerFactory = PowerMockito.mock(ManagerFactory.class);
PowerMockito.when(ManagerFactory.getInstance()).thenReturn(managerFactory);
  • doReturn和thenReturn的区别
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SyncInformHandler syncInformHandler = PowerMockito.mock(SyncInformHandler.class);
PowerMockito.doReturn(1).when(syncInformHandler).getReturn();
Assert.assertEquals(1, syncInformHandler.getReturn());
PowerMockito.when(syncInformHandler.getReturn()).thenReturn(2);
Assert.assertEquals(2, syncInformHandler.getReturn());

以上的测试用例代码是可以正常跑通的,这里说明二者都可用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PowerMockito.mockStatic(ManagerFactory.class);
managerFactory = PowerMockito.mock(ManagerFactory.class);
PowerMockito.when(ManagerFactory.getInstance()).thenReturn(managerFactory);
// 不能用如下写法
// PowerMockito.doReturn(managerFactory).when(ManagerFactory.getInstance());

以上的代码就显示出doReturn和thenReturn的区别了,thenReturn之前的when里的参数是可以调用响应方法的,但是doReturn后面的when只能是一个Object类型的参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
List list = new LinkedList();
List spy = PowerMockito.spy(list);
// 以下会抛出IndexOutOfBoundsException异常
// PowerMockito.when(spy.get(0)).thenReturn("sss");
PowerMockito.doReturn("sss").when(spy).get(0);
Assert.assertEquals("sss", spy.get(0));

以上代码,注释掉的不能用,会抛出IndexOutOfBoundsException异常,因为thenReturn会调用真实的方法执行,而doReturn不会,只会执行stubbed(插桩)方法

  • mock类中private变量
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IMInternal imInternal = PowerMockito.mock(IMInternal.class);
PushInfo pushInfo = PowerMockito.mock(PushInfo.class);
PowerMockito.doReturn(pushInfo).when(imInternal).getPushInfo();
syncInformHandler = PowerMockito.mock(SyncInformHandler.class);
Whitebox.setInternalState(syncInformHandler, "imInternal", imInternal);

这里mock了SyncInformHandler类中的private类型的全局变量imInternal,其实就是通过Whitebox.setInternalState方法把我们外部生成的imInternal对象通过反射set进去

  • 对于一个mock对象,有时候我们并不需要里面所有的方法都被mock,有一些方法我们还是想真正执行,可用:doCallRealMethod()方法来标记某一个方法要被真的调用:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PowerMockito.doCallRealMethod().when(syncInformHandler).handle(Mockito.any(PushRequest.class), Mockito.any(PushResponse.class));
  • 对于一个new出来的对象,我们想控制该对象中某些方法的返回值,由于不是mock对象,所以无法mock里面的方法,但是可以通过PowerMockito.spy()来监视这个real object
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
List list = new LinkedList();
List spy = PowerMockito.spy(list);
PowerMockito.doReturn("sss").when(spy).get(0);
Assert.assertEquals("sss", spy.get(0));

这里有一点需要注意,Mockito.spy()和PowerMockito.spy()区别在于Mockito无法监视对象的final方法,但是PowerMockito可以,其实PowerMockito是基于Mockito的基础上拓展开发的,所以功能更加强大,也兼容了Mockito的功能

  • mock对象自定义的构造函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SyncInformHandler syncInformHandler = PowerMockito.mock(SyncInformHandler.class);

如果是用以上方式去mock出来的对象,那么是通过默认空参数的构造函数去mock的,想通过自定义带参数的构造函数去mock可用如下方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SyncInformHandler syncInformHandler = PowerMockito.mock(SyncInformHandler.class);
PowerMockito.whenNew(SyncInformHandler.class).withArguments(Mockito.anyInt()).thenReturn(syncInformHandler);
SyncInformHandler s1 = new SyncInformHandler(2);
PowerMockito.doReturn(5).when(s1).getReturn();
Assert.assertEquals(5, s1.getReturn());

当使用new SyncInformHandler(2)这个构造函数来创建对象s1的时候,whenNew就会强行把s1替换成我们mock的对象syncInformHandler,然后就能够对s1对象使用各种mock方法了,为什么要这么玩?总感觉多次一举,直接使用mock对象不就好了?我认为,这里可能会更加灵活,mock对象无法指定构造函数,而whenNew可以针对性的指定哪些构造函数new出来的对象是可以使用mock的,哪些构造函数new出来的对象是无需mock的

  • 验证方法是否有被执行过,验证方法被调用的次数;有时候一个方法并没有返回值,所以没办法通过判断返回值的方式来验证结果是否是我们锁预期的,因此可通过检测方法中某一个子方法是否被调用过,被调用的次数来检测是否符合我们的预期:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
验证public方法是否被执行过
Mockito.verify(syncKeyManager, Mockito.never()).putServerSyncKey(Mockito.anyLong(), Mockito.anyLong());
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 验证private方法是否被执行过2次
PowerMockito.verifyPrivate(syncInformHandler, Mockito.times(2)).invoke("dealSyncInform", Mockito.any(PushResponse.class));
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 验证指定构造函数是否被执行过,这个要和whenNew结合使用
SyncInformHandler mock = PowerMockito.mock(SyncInformHandler.class);
        PowerMockito.whenNew(SyncInformHandler.class).withArguments(Mockito.any(IMInternal.class)).thenReturn(mock);
SyncInformHandler read = new SyncInformHandler(null);
        PowerMockito.verifyNew(SyncInformHandler.class).withArguments(Mockito.any(IMInternal.class));

如何编写单元测试用例

  • 首先,要理清楚程序逻辑,罗列出程序所有重要的分支,一般方案设计的时候会画一个流程图,可以把流程图细化下,满足什么条件跑if分支,满足什么条件跑else分支
  • 针对每一条程序逻辑分支流程编写一个单元测试用例方法,如果该程序逻辑分支很简单,可以把几个逻辑分支合并成一个单元测试方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RunWith(PowerMockRunner.class)
@PrepareForTest({SyncInformHandler.class})
public class ResponseDispatcherTest {

    public void testJUnit() {
        if (isPass()) {
            System.out.println("pass");
        } else {
            System.out.println("no pass");
        }
    }

    public boolean isPass() {
        return true;
    }

    @Test
    public void testStart() throws Exception {
        ResponseDispatcherTest responseDispatcherTest = PowerMockito.mock(ResponseDispatcherTest.class);
        PowerMockito.doCallRealMethod().when(responseDispatcherTest).testJUnit();

        PowerMockito.doReturn(false).when(responseDispatcherTest).isPass();
        responseDispatcherTest.testJUnit();

        PowerMockito.doReturn(true).when(responseDispatcherTest).isPass();
        responseDispatcherTest.testJUnit();
    }
}

testJUnit方法中有两条逻辑分支,那么我们就能控制isPass()返回值来分别执行到这两条逻辑分支,这里只是举一个简单的编写用例,先不用看方法命名规范性问题

  • 对于android程序来说,很多时候代码里面可能会有android的一些相关的类,接口等,但是在JUnit环境下,是没有这些环境的,例如说Context,任何运行到android类的地方都会直接崩溃,这时候需要把这些类或者方法mock掉,返回我们指定的值,Java单元测试的重点是测试Java代码的逻辑,具体的android相关的是不关注的,可以通过android单元测试来测试android的相关代码
  • 每一个单元测试方法都要写详细的注释,减少后面其他人来维护这个单元测试的成本
  • 单元测试用户针对类去写,一个类:className对应一个单元测试用例类:TestclassName,而且包名是一样的,这样在单元测试用例类中就能直接访问protected方法了
  • 单元测试的编写也可以有“模块测试”与“集成测试”的概念,比如说一个方法里面执行了6个子方法,我们可分别验证这6个子方法的正确性,然后再验证这6个子方法合起来跑的结果是否是正确的,也就是验证一个功能处理逻辑的正确性
  • 误区:场景测试,针对一些比较复杂场景的方案设计和编码,罗列出原先设计方案所支持的那些场景,然后用单元测试模拟这些场景来测试,例如我想测试一些多线程场景的问题,所以在测试方法里会开启多个线程,而且在这些线程运行结束之前这个测试方法不能结束,所以要wait,这样有可能导致这个测试方法运行很久,对于一个大工程来说,测试类可能有几十个,测试方法可能有上百个,那么会导致这个工程跑单元测试的时候跑很久才结束,可能会大大降低jinkens的编译速度,因为理论上一个单元测试方法的执行时间都是ms级别的,针对这种问题,考虑放到androidTest下去测试,不要在逻辑单元测试中做
Android单元测试,在androidTest目录下
  • 四大组件的测试(生命周期)
  • UI测试
  • sqlite数据库测试
  • 文件存储测试(sd卡,SharedPreferences)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.11.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JAVA实战:如何让单元测试覆盖率达到80%甚至以上
单元测试(unit testing)是指对软件中的最小可测试单元进行检查和验证。它是软件测试中的一种基本方法,也是软件开发过程中的一个重要步骤。
你可以叫我老白
2023/03/21
4.1K1
JAVA实战:如何让单元测试覆盖率达到80%甚至以上
有了它(powerMocker)再也不怕单元测试不达标了!
目前应用比较普遍的java单元测试工具junit4+Mock(Mockito、jmock、EasyMock、powermock)。为什么会选powermock? 在做单元测试的时候,我们会发现我们要测试的方法会有很多外部依赖的对象或者一些其他服务的调用比如说(发送邮件,网络通讯,soa调用)。而我们没法控制这些外部依赖的对象。为了解决这个问题,我们需要用到Mock来模拟这些外部依赖的对象,从而控制它们。只关心我们自己的业务逻辑是否正确。而这时powermock就起作用了,它不仅可以mock外部的依赖,还可以mock私有方法、final方法,总之它的功能很强大。
java金融
2020/08/04
3.3K0
Mockito模拟进行单元测试
    MOCK意思是模拟的意思,主要被用来进行数据的人工组织,不会真正地调用第三方服务器,类似redis,mysql等都不会调用,也不用关心数据底层是如何进行处理的,我们要做的只是将本单元的逻辑进行单元测试,验证数据的逻辑处理性,而其中mock较好的框架就是Mockito。
chinotan
2019/07/15
9.7K0
Mockito模拟进行单元测试
使用 Junit + Mockito 实践单元测试
相信做过开发的同学,都多多少少写过下面的代码,很长一段时间我一直以为这就是单元测试...
JMCui
2020/05/06
4.9K0
Spock框架Mock对象、方法经验总结
近期已然陷入了单元测试的汪洋大海,上万行的代码突然要求起来单元测试覆盖率,着实很恐怖的。最经过艰苦的抗争学习之后,终于迈过了技术这个坎儿,特来分享一下最近踩坑的经历,和一些典型的使用场景案例分享。
FunTester
2022/02/08
5.4K4
junit4整合PowerMockito进行单元测试
所以我们在单测中,往往会使用mock的方式对这些代码做一个数据的模拟,从而达到对代码进行测试的一个目的。
半月无霜
2023/10/18
1.4K0
junit4整合PowerMockito进行单元测试
单元测试框架spock和Mockito应用
spock是一款基于Groovy语言的单元测试框架,其基础也是Java的Junit,目前最新版已经到了2.0,但对Groovy和响应的Java版本要求较高,具体信息参考:Spock 2.0 M1版本初探。
FunTester
2020/05/18
2.5K0
PowerMock(一):PowerMock的使用
现在流行的测试驱动开发TDD(Test-Driven Development) ,是敏捷开发中一项核心实践和技术。也是一种设计方法论。其中最重要的一环就是使用单元测试。单元测试是保证代码质量的一个重要手段,通过单元测试我们可以快速的测试代码的各个分支,各种场景,代码重构时只需要重新跑下单元测试就是能知道代码潜在的问题。单元测试是通过Mock的方式调用被测试的方法,其有如下几个优点:
码农飞哥
2021/08/18
8.1K0
使用PowerMock进行单元测试
单元测试可以提高测试开发的效率,减少代码错误率,提高代码健壮性,提高代码质量。在Spring框架中常用的两种测试框架:PowerMockRunner和SpringRunner两个单元测试,鉴于SpringRunner启动的一系列依赖和数据连接的问题,推荐使用PowerMockRunner,这样能有效的提高测试的效率,并且其提供的API能覆盖的场景广泛,使用方便,可谓是Java单元测试之模拟利器。
Dream城堡
2022/01/07
3.7K0
关于单元测试,其实你也可以这样来写
在TDD领域Mock框架有很多,比如EasyMock,JMock,Mockito。可能有些同学会好奇了,为什么要重点把powermock拿出来呢,因为powermock可以解决前面三种框架不能解决的问题,而且powermock也是是单元测试中极其强大的测试框架。
软件测试君
2019/12/19
6680
单元测试
  每个开发人员都写过很多代码、函数,但是你能保证你写的每个函数都能执行并且正常吗?   我们太多时间站在功能需求的角度来审视我们的代码,认为需求实现功能逻辑正常,我们就完成了自己的使命。功能逻辑固然重要这个也是我们的目标。但是仅此而已吗,首先作为开发人员要知道,代码的终极目标有两个:实现需求保证逻辑正常、保证代码质量和可维护性。测试人员只能帮助我们查漏需求是否完整实现,对于代码质量和可维护性是需开发自己保证的,所以单元测试必不可少。
OPice
2019/11/11
1.8K0
Java单元测试框架之Mockito指南
Mockito 框架是用于单元测试的基本框架,本文将介绍其使用使用方法及作用,也会给出相对应的例子作为参考。详细的业务场景可以参考一下项目中的单元测试编写。文中最后也有关于单元测试的相关文章链接,大家可以去详细了解一下。
苦叶子
2024/04/14
3.5K0
Java单元测试框架之Mockito指南
如何实现时间穿越?PowerMock系列之2
在笔者测试的某些系统中,存在一些与时间相关的系统功能。如某个程序会在每天的指定时间,如下午6点被触发,完成与外部公司的数据交换。 在系统测试时,往往需要通过修改linux的系统时间等方式来触发上述功能进而完成测试过程。这时非常不方便的,而且有时候还会因为修改了操作系统时间忘记改回,导致其它应用产生问题,如连接超时等。当然也有在隔离网络内提供NTP时钟服务的方案,只是需要网络层面的支持,测试成本较高,一般用于系统测试中。 而在单元测试时,为了不受外部约束,保证测试用例的健壮性,需要对系统时间进行mock。如以下的一个被测方法
Antony
2020/12/01
6660
代码整洁之道-读书笔记之单元测试
TDD:测试驱动开发,先写测试,再写逻辑代码,通过单测,写逻辑代码,依次循环,知道所有逻辑都完成
特特
2022/11/16
6390
Mockito和PowerMock用法
在单元测试中,我们往往想去独立地去测一个类中的某个方法,但是这个类可不是独立的,它会去调用一些其它类的方法和service,这也就导致了以下两个问题:外部服务可能无法在单元测试的环境中正常工作,因为它们可能需要访问数据库或者使用一些其它的外部系统。我们的测试关注点在于这个类的实现上,外部类的一些行为可能会影响到我们对本类的测试,那也就失去了我们进行单测的意义。
一滴水的眼泪
2020/09/24
3.4K0
Spock框架Mock静态资源经验汇总
前面讲了Spock框架Mock对象、方法经验总结,今天分享一下Spock框架中Mock静态资源的实践经验汇总。分成「静态资源」和「混合场景」。
FunTester
2022/02/08
1.8K0
PowerMockito 简介「建议收藏」
1 在需要执行单测的类上注解@RunWith(PowerMockRunner.class) 2 对于需要mock私有方法的需要注解@PrepareForTest(FooServiceImpl.class)
全栈程序员站长
2022/11/01
7690
Mocktio 使用(下)
thenReturn 用来指定特定函数和参数调用的返回值。thenReturn 中可以指定多个返回值,在调用时返回值依次出现。若调用次数超过返回值的数量,再次调用时返回最后一个返回值。
HLee
2021/10/11
3.7K0
Mocktio 使用(下)
单元测试指南
在我们公司中要做单元测试,确实比较难,因为公司缺少这种氛围,有也只是局部的,大多数工程师没有这方面的习惯和素养,很多人都是有一定的抵触的心理,经过我私下的了解大概有以下几种原因吧。
Abalone
2022/07/14
6.4K0
单元测试指南
Spock单元测试框架以及在美团优选的实践
Spock是国外一款优秀的测试框架,基于BDD(行为驱动开发)思想实现,功能非常强大。Spock结合Groovy动态语言的特点,提供了各种标签,并采用简单、通用、结构化的描述语言,让编写测试代码更加简洁、高效。目前,美团优选物流绝大部分后端服务已经采用了Spock作为测试框架,在开发效率、可读性和维护性方面均取得了不错的收益。
测试开发社区
2021/08/23
3.4K0
Spock单元测试框架以及在美团优选的实践
相关推荐
JAVA实战:如何让单元测试覆盖率达到80%甚至以上
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验