场景
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); } }