多人协作下的调试

一、介绍

1.1 介绍

        1. 多人协作下的测试有什么不同(Mock)

        2. 如何编写单元测试(依赖外部、不依赖外部两种情况)

        3. 如何排查慢方法、测方法耗时

二、测试与调试

2.1 多人协作下的测试有什么不同

        1. 依赖别人开发的接口

        2. 联调?等待?反复沟通?

        3. Mock技术

Mockito

        古巴最著名的鸡尾酒Mojito

        使用最广泛的模拟库之一

Mockito的能力有多强?

        ​​​​​​​引入依赖

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>3.9.0</version>
      <scope>test</scope>
    </dependency>

        编写测试类。创建Mock对象,Mock对象的返回。Spy来部分模拟某对象。@Mock @Spy注解。

package com.imooc.cloud.mall.practice.user.service.impl;

import java.util.HashMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * 描述:     TODO
 */
@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public class UserServiceImplTest {
//    @Mock //对等1
//    HashMap myHashMap;
    @Test
    public void myFirstMock() {
        HashMap mockHashMap = Mockito.mock(HashMap.class); //对等1
        Mockito.when(mockHashMap.size()).thenReturn(5);
        System.out.println(mockHashMap.size());
        mockHashMap.put(new Object(), new Object());
        System.out.println(mockHashMap.size());

    }

    @Spy //对等2
    HashMap<String, String> hashMap = new HashMap<>();

    @Test
    public void myFirstSpy() {
        //HashMap<String, String> hashMap = new HashMap<>(); //对等2
        //spy定制的意思。对一部分想定制的方法进行定制,不想定制的方法用原来的能力。
        HashMap<String, String> spy = Mockito.spy(hashMap);
        spy.put("1","2");
        System.out.println(spy.size());
        spy.put("2","3");
        Mockito.when(spy.size()).thenReturn(10);
        System.out.println(spy.size());

    }
}

 2.2 如何编写单元测试

平常的单元测试

package com.imooc.cloud.mall.practice.user.service.impl;

import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.imooc.cloud.mall.practice.common.exception.ImoocMallException;
import com.imooc.cloud.mall.practice.common.exception.ImoocMallExceptionEnum;
import com.imooc.cloud.mall.practice.user.model.dao.UserMapper;
import com.imooc.cloud.mall.practice.user.model.pojo.User;
import java.time.Duration;
import java.time.Instant;
import java.util.LinkedList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit4.statements.SpringRepeat;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringRunner.class) //需要Spring注入的能力
@SpringBootTest
public class UserTest {

    @Autowired
    UserMapper userMapper;

    @Test
    @Transactional //测试时,对数据库的修改会在测试结束后回滚
    @Rollback(true)//事务自动回滚,默认是true。更加明显的事务回滚标记。
    //普通的不使用mock的单元测试
    public void testUpdateInformation() {
        //1 currentTimeMillis
        long start = System.currentTimeMillis();

        User user = new User();
        user.setId(9);
        user.setPersonalizedSignature("新签名");

        long finish = System.currentTimeMillis();
        long timeElapsed = finish - start;
        System.out.println("currentTimeMillis:" + timeElapsed);

        //2 nanoTime

        //更新个性签名
        long start2 = System.nanoTime();

        int updateCount = userMapper.updateByPrimaryKeySelective(user);

        long finish2 = System.nanoTime();
        timeElapsed = finish2 - start2;
        System.out.println("nanoTime:" + timeElapsed / 1000000);


        if (updateCount > 1) {
            throw new ImoocMallException(ImoocMallExceptionEnum.UPDATE_FAILED);
        }
        //3 Instant
        Instant start3 = Instant.now();
        User newUser = userMapper.selectByPrimaryKey(user.getId());
        Instant finish3 = Instant.now();
        long timeElapsed3 = Duration.between(start3, finish3).toMillis();
        System.out.println(timeElapsed3);

        Assert.assertEquals(newUser.getPersonalizedSignature(), user.getPersonalizedSignature());
    }
}

带远程调用的单元测试

package com.imooc.cloud.mall.practice.cartorder.service.impl;

import com.imooc.cloud.mall.practice.cartorder.feign.ProductFeignClient;
import com.imooc.cloud.mall.practice.cartorder.model.pojo.Product;
import com.imooc.cloud.mall.practice.cartorder.model.vo.CartVO;
import com.imooc.cloud.mall.practice.common.common.Constant.SaleStatus;
import com.imooc.cloud.mall.practice.common.exception.ImoocMallException;
import com.imooc.cloud.mall.practice.common.exception.ImoocMallExceptionEnum;
import junit.framework.TestCase;
import org.apache.commons.lang.time.StopWatch;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * 描述:     TODO
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderServiceImplTest{

    @Mock
    ProductFeignClient productFeignClient;

    @Test
    public void validSaleStatusAndStockTest() throws InterruptedException {
        StopWatch watch = new StopWatch(); //StopWatch代码
        watch.start(); //StopWatch代码
        CartVO cartVO = new CartVO();
        cartVO.setProductId(27);
        cartVO.setQuantity(1);
        Product fakeProduct = new Product();
        fakeProduct.setStatus(1);
        fakeProduct.setStock(4);
        Thread.sleep(1000);
        watch.split(); //StopWatch代码
        System.out.println("split time:" + watch.getSplitTime()); //StopWatch代码

        Thread.sleep(1500);
        Mockito.when(productFeignClient.detailForFeign(27)).thenReturn(fakeProduct);
        Product product = productFeignClient.detailForFeign(cartVO.getProductId());
        long time = watch.getTime(); //StopWatch代码
        System.out.println("time elapsed:" + time); //StopWatch代码

        watch.suspend(); //StopWatch代码 暂停
        //判断商品是否存在,商品是否上架
        if (product == null || product.getStatus().equals(SaleStatus.NOT_SALE)) {
            throw new ImoocMallException(ImoocMallExceptionEnum.NOT_SALE);
        }
        Thread.sleep(3000);
        //判断商品库存
        if (cartVO.getQuantity() > product.getStock()) {
            throw new ImoocMallException(ImoocMallExceptionEnum.NOT_ENOUGH);
        }
        watch.resume(); //StopWatch代码 恢复
        Thread.sleep(500);
        System.out.println("time elapsed:" + watch.getTime()); //StopWatch代码

        Assert.assertNotNull(product);
        Assert.assertEquals(1, (int)product.getStatus());
        Assert.assertTrue(product.getStock() > cartVO.getQuantity());
    }

}

2.3 如何排查慢方法,测方法耗时

        currentTimeMillis()(有缺陷,用的系统时间为标准,代码可能修改系统时间,导致测量结果不准确)

        nanoTime()(纳秒,1000000纳秒=1毫秒)

        Instant类

        StopWatch(计时,split,暂停恢复{跳过不计时某部分代码} )

        代码在上面

三、总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengbo_eva

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值