• Java中进行单元测试junit.Assert断言、Mockito模拟对象、verify验证模拟结果、Java8中lambda的peek方法使用


    场景

    Java8新特性-Stream对集合进行操作的常用API:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126070657

    在上面使用流操作时需要用到单元测试的情况。

    在Junit单元测试方法中使用org.junit.Assert进行断言校验。

    org.junit.Assert

    常用方法如下

    //    void assertEquals(Object object,Object object) 判断输入的参数值是否相等
    //    void assertFalse(boolean condition) 判断输入参数是否为false
    //    void assertTrue(boolean condition) 判断输入参数是否为true
    //    void assertNotNull(Object object) 判断输入参数是否不为null
    //    void assertNull(Object object) 判断输入参数是否为null
    //    void assertSame(Object object,Object object) 判断引用对象是否相等(必须传入引用类型)
    //    void assertNotSame(Object object,Object object) 判断引用对象是否不相等
    //    assertEquals(double expected, double actual, double delta) 检查指定精度的double值是否相等(delta为可以波动的范围)

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    assertSame

        @Test
        public void test2(){
            String expected = "badao";
            String actucal = "badao";
            assertSame(expected,actucal);
        }

    assertNotSame

        @Test
        public void test3(){
            String expected = "badao";
            String actucal = "badao";
            assertNotSame(expected,actucal);
        }

    assertEquals

        @Test
        public void test4(){
            int expected = 123;
            int actucal = 123;
            assertEquals(expected,actucal);
        }

    assertNotEquals

        @Test
        public void test5(){
            int expected = 123;
            int actucal = 123;
            assertNotEquals(expected,actucal);
        }

    assertNull

        @Test
        public void test6(){
            Object object = null;
            assertNull(object);
        }

    assertNotNull

        @Test
        public void test7(){
            Object object = null;
            assertNotNull(object);
        }

    assertTrue

        @Test
        public void test8(){
            assertTrue(1>2);
        }

    assertFalse

        @Test
        public void test9(){
            assertFalse(1>2);
        }

    断言通过时

    断言不通过时

    Mockito

    Mockito是mocking框架,它让你用简洁的API做测试。而且Mockito简单易学,它可读性强和验证语法简洁。

    Mockito 是一个针对 Java 的单元测试模拟框架,它与 EasyMock 和 jMock 很相似,都是为了简化单元测试过程中测试

    上下文 ( 或者称之为测试驱动函数以及桩函数 ) 的搭建而开发的工具。相对于 EasyMock 和 jMock,

    Mockito 的优点是通过在执行后校验哪些函数已经被调用,消除了对期望行为(expectations)的需要。

    其它的 mocking 库需要在执行前记录期望行为(expectations),而这导致了丑陋的初始化代码。

    mock示例

    1、mock一个Random随机数对象,并且设置当调用nextInt方法时,永远返回100

        @Test
        public void test1(){
            Random mockRandom = mock(Random.class);
            //指定调用nextInt方法时,永远返回100
            when(mockRandom.nextInt()).thenReturn(100);
            Assert.assertEquals(100,mockRandom.nextInt());
        }

    2、mock一个ArrayList

        @Test
        public void test10(){
            ArrayList mockArrayList =  mock(ArrayList.class);
            //Assert.assertTrue(mockArrayList instanceof List);
            when(mockArrayList.add(1)).thenReturn(true);
            Assert.assertTrue(mockArrayList.add(1));
        }

    3、mock一个Iterator迭代器,并且设置当调用next方法时抛出空指针异常

        @Test
        public void test11(){
            Iterator iterator = mock(Iterator.class);
            when(iterator.next()).thenReturn("Hello");
            //方法抛出异常
            doThrow(new NullPointerException()).when(iterator).next();
            iterator.next();
        }

    mock的verify方法

    Mockito提供了verify()方法来验证这个mock实例的某个方法是否被调用,调用了几次,是否带有参数以及带有何种参数等

    示例

        @Test
        public void test12(){
            List mockedList = mock(List.class);
            //Mockito提供了verify()方法来验证这个mock实例的某个方法是否被调用,调用了几次,是否带有参数以及带有何种参数等
            mockedList.add("aa");
            //验证方法执行过一次
            verify(mockedList,atLeastOnce()).add("aa");
        }

    会验证mockedList是否至少执行过一次

    其中atLeastOnce()是静态方法。

    import static org.mockito.Mockito.*;

    除了该方法还有

        @Test
        public void test12(){
            List mockedList = mock(List.class);
            //Mockito提供了verify()方法来验证这个mock实例的某个方法是否被调用,调用了几次,是否带有参数以及带有何种参数等
            mockedList.add("aa");
            //验证方法执行过一次
            //verify(mockedList,atLeastOnce()).add("aa");
            //验证执行次数,这里为2次
            //verify(mockedList,times(2)).add("aa");
            //最多调用一次
            //verify(mockedList,atMostOnce()).add("bbb");
            //对参数也会校验
            verify(mockedList,never()).add("aa");//不通过
            verify(mockedList,never()).add("aaa");//通过
        }

    比如这里的times(2)代表验证次数是否执行2次,如果期待2次,但是实际只执行一次,则会报错

    不仅对方法,还会对方法参数进行校验,比如上面执行add("aa")一次之后,验证add("aa")与add("aaa")是不一样的。

    Java8中流操作时进行调试--peek

    假设你要在集合上进行大量操作,要调试代码,你希望看到每一步操作的步骤是什么。

    可以在每一步打印出集合中的值,这在流中很难做到。

    peek方法,能让你查看每个值,同时能继续操作流。

    示例

    1、简单示例

        //不会有任何输出
        @Test
        public void test13() {
            Stream.of("1","2","3")
                    .peek(s -> System.out.println(s));
        }

    2、对象list

        //会对对象进行操作并输出
        @Test
        public void test14() {
            Album album1 = Album.builder()
                    .albumName("album1")
                    .trackList(new ArrayList<Track>(){{
                        this.add(Track.builder().trackName("a").length(60f).build());
                        this.add(Track.builder().trackName("b").length(70f).build());
                        this.add(Track.builder().trackName("c").length(80f).build());
                        this.add(Track.builder().trackName("d").length(90f).build());
                    }})
                    .build();
            album1.getTrackList().stream().peek(album ->{album.setTrackName("badao");}).forEach(System.out::println);
        }

    3、实际应用

        //peek方法,能让你查看每个值,同时能继续操作流
        @Test
        public void test15() {
            Album album1 = Album.builder()
                    .albumName("album1")
                    .trackList(new ArrayList<Track>(){{
                        this.add(Track.builder().trackName("a").length(60f).build());
                        this.add(Track.builder().trackName("b").length(70f).build());
                        this.add(Track.builder().trackName("c").length(80f).build());
                        this.add(Track.builder().trackName("d").length(90f).build());
                    }})
                    .build();
            album1.getTrackList()
                    .stream()
                    //输出流中的值,同时避免了重复的流操作,不用再forEach,可用于输出定向到现有的日志系统中
                    .peek(album ->{
                        System.out.println(album.getTrackName()+"--"+album.getLength());})
                    .map(a->a.getTrackName())
                    .collect(Collectors.toList())
                    .forEach(System.out::println);
        }

    以上示例代码汇总

    package com.ruoyi.demo.java8demo;
    
    import com.ruoyi.demo.domain.Album;
    import com.ruoyi.demo.domain.Track;
    import org.junit.Assert;
    import org.junit.Test;
    import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import static org.junit.Assert.*;
    import static org.mockito.Mockito.*;
    
    public class unitTestDemo {
    
    //    void assertEquals(Object object,Object object) 判断输入的参数值是否相等
    //    void assertFalse(boolean condition) 判断输入参数是否为false
    //    void assertTrue(boolean condition) 判断输入参数是否为true
    //    void assertNotNull(Object object) 判断输入参数是否不为null
    //    void assertNull(Object object) 判断输入参数是否为null
    //    void assertSame(Object object,Object object) 判断引用对象是否相等(必须传入引用类型)
    //    void assertNotSame(Object object,Object object) 判断引用对象是否不相等
    //    assertEquals(double expected, double actual, double delta) 检查指定精度的double值是否相等(delta为可以波动的范围)
    
        @Test
        public void test2(){
            String expected = "badao";
            String actucal = "badao";
            assertSame(expected,actucal);
        }
    
        @Test
        public void test3(){
            String expected = "badao";
            String actucal = "badao";
            assertNotSame(expected,actucal);
        }
    
        @Test
        public void test4(){
            int expected = 123;
            int actucal = 123;
            assertEquals(expected,actucal);
        }
    
        @Test
        public void test5(){
            int expected = 123;
            int actucal = 123;
            assertNotEquals(expected,actucal);
        }
    
        @Test
        public void test6(){
            Object object = null;
            assertNull(object);
        }
    
        @Test
        public void test7(){
            Object object = null;
            assertNotNull(object);
        }
    
        @Test
        public void test8(){
            assertTrue(1>2);
        }
    
        @Test
        public void test9(){
            assertFalse(1>2);
        }
    
        @Test
        public void test1(){
            Random mockRandom = mock(Random.class);
            //指定调用nextInt方法时,永远返回100
            when(mockRandom.nextInt()).thenReturn(100);
            Assert.assertEquals(100,mockRandom.nextInt());
        }
    
        @Test
        public void test10(){
            ArrayList mockArrayList =  mock(ArrayList.class);
            //Assert.assertTrue(mockArrayList instanceof List);
            when(mockArrayList.add(1)).thenReturn(true);
            Assert.assertTrue(mockArrayList.add(1));
        }
    
        @Test
        public void test11(){
            Iterator iterator = mock(Iterator.class);
            when(iterator.next()).thenReturn("Hello");
            //方法抛出异常
            doThrow(new NullPointerException()).when(iterator).next();
            iterator.next();
        }
    
        @Test
        public void test12(){
            List mockedList = mock(List.class);
            //Mockito提供了verify()方法来验证这个mock实例的某个方法是否被调用,调用了几次,是否带有参数以及带有何种参数等
            mockedList.add("aa");
            //验证方法执行过一次
            //verify(mockedList,atLeastOnce()).add("aa");
            //验证执行次数,这里为2次
            //verify(mockedList,times(2)).add("aa");
            //最多调用一次
            //verify(mockedList,atMostOnce()).add("bbb");
            //对参数也会校验
            verify(mockedList,never()).add("aa");//不通过
            verify(mockedList,never()).add("aaa");//通过
        }
    
    
        //不会有任何输出
        @Test
        public void test13() {
            Stream.of("1","2","3")
                    .peek(s -> System.out.println(s));
        }
    
        //会对对象进行操作并输出
        @Test
        public void test14() {
            Album album1 = Album.builder()
                    .albumName("album1")
                    .trackList(new ArrayList<Track>(){{
                        this.add(Track.builder().trackName("a").length(60f).build());
                        this.add(Track.builder().trackName("b").length(70f).build());
                        this.add(Track.builder().trackName("c").length(80f).build());
                        this.add(Track.builder().trackName("d").length(90f).build());
                    }})
                    .build();
            album1.getTrackList().stream().peek(album ->{album.setTrackName("badao");}).forEach(System.out::println);
        }
    
        //peek方法,能让你查看每个值,同时能继续操作流
        @Test
        public void test15() {
            Album album1 = Album.builder()
                    .albumName("album1")
                    .trackList(new ArrayList<Track>(){{
                        this.add(Track.builder().trackName("a").length(60f).build());
                        this.add(Track.builder().trackName("b").length(70f).build());
                        this.add(Track.builder().trackName("c").length(80f).build());
                        this.add(Track.builder().trackName("d").length(90f).build());
                    }})
                    .build();
            album1.getTrackList()
                    .stream()
                    //输出流中的值,同时避免了重复的流操作,不用再forEach,可用于输出定向到现有的日志系统中
                    .peek(album ->{
                        System.out.println(album.getTrackName()+"--"+album.getLength());})
                    .map(a->a.getTrackName())
                    .collect(Collectors.toList())
                    .forEach(System.out::println);
        }
    }
  • 相关阅读:
    21班考试总结
    性别
    2019.08.20上课笔记2
    2019.08.20上课笔记3
    2019.08.20上课笔记1
    单词2
    数据类和运算符
    2019.08.14单词1
    2019.08.14上课笔记1
    request.get... getHeader 能取得的信息 参数
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/16821420.html
Copyright © 2020-2023  润新知