1、SpringBoot如何开启单元测试
1.1 修改pom.xml文件,引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
1.2、在test创建一个类
package com.fcors.fcors;
import org.junit.Test;
public class OptionalTest {
@Test
public void testOptional(){
System.out.println("单元测试");
}
}
1.3、执行单元测试
Optional参考地址:https://blog.csdn.net/weixin_45821811/article/details/115656637
2、Optional的使用详解
2.1、Optional介绍
- Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象
- Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测
- Optional 类的引入很好的解决空指针异常
2.2、构建Optional
构建一个Optional对象;方法有:empty( )、of( )、ofNullable( )
//返回一个描述给定值的Optional ,如果不为null ,则返回一个空的Optional 。
//参数:值–描述的可能为null值
//类型参数:<T> –值的类型
//返回值:一个Optional与如果指定值是非当前值null ,否则一个空Optional
Optional.ofNullable("");
//返回一个Optional描述给定的非null值。
//参数:value –要描述的值,必须为非null
//类型参数:<T> –值的类型
//返回值:存在值的Optional
Optional.of("");
//返回一个空的Optional实例。 此Optional没有值。
//类型参数:<T> –不存在的值的类型
//返回值:一个空的Optional
//api注意:尽管这样做可能很诱人,但应通过将==与Optional.empty()返回的实例进行比较来避免测试对象是否为空。
// 不能保证它是一个单例。
// 而是使用isPresent()
Optional.empty();
构建测试:
2.2.1、创建一个MyUser的类
package com.fcors.fcors;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class MyUser {
private String name1;
private String name2;
}
2.2.2、构造Optional
package com.fcors.fcors;
import org.junit.Test;
import java.util.Optional;
public class OptionalTest {
@Test
public void testOptional(){
Optional s1 = Optional.ofNullable(null);
// 构建一个value不可以为null的optional对象,如果of()的入参为null会报空指针异常;
Optional<MyUser> s2 = Optional.of(new MyUser("阿辉2","123456"));
// 构建一个value可以为null的optional对象;
Optional<MyUser> s3 = Optional.ofNullable(null);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
/* 输出
* Optional.empty
* Optional[MyUser{id='阿辉2', username='123456'}]
* Optional.empty
**/
}
}
2.3、获取类
package com.fcors.fcors;
import org.junit.Test;
import java.util.Optional;
public class OptionalTest {
@Test
public void testOptional(){
Optional<MyUser> userInfoEmptyOpt = Optional.empty();
Optional<MyUser> userInfoOpt = Optional.of(new MyUser("阿飞","123456"));
// 1、直接获取,注意如果value==null,会报NoSuchElementException异常
MyUser userInfo1 = userInfoOpt.get();
// 2、orElse可以传入一个UserInfo类型的对象作为默认值;
// 当value!=null时,返回value值;
// 当value==null时,返回默认值作为代替;
MyUser userInfo2 = userInfoEmptyOpt.orElse(new MyUser("阿飞1","123456"));
// 3、orElseGet和orElse不同的是orElseGet可以传入一段lambda表达式;
// 当value!=null时,返回value值;
// 当value==null时,使用该lambda返回的对象作为默认值;
MyUser userInfo3 = userInfoEmptyOpt.orElseGet(() -> new MyUser("阿飞2","123456"));
// 4、orElseThrow可以传入一段lambda表达式,lambda返回一个Exception;
// 当value!=null时,返回value值;
// 当value==null时,抛出该异常;
MyUser userInfo4 = userInfoOpt.orElseThrow(NullPointerException::new);
System.out.println(userInfo2);
System.out.println(userInfo3);
System.out.println(userInfo4);
// 输出如下:
// UserInfo(username=阿飞, password=123456)
// UserInfo(username=阿飞1, password=123456)
// UserInfo(username=阿飞2, password=123456)
// UserInfo(username=阿飞, password=123456)
}
}
2.4、判断类
package com.fcors.fcors;
import org.junit.Test;
import java.util.Optional;
public class OptionalTest {
@Test
public void testOptional(){
Optional<MyUser> myUser1 = Optional.empty();
Optional<MyUser> myUser2 = Optional.of(new MyUser("阿飞", "123456"));
// filter传入一个lambda,lambda返回值为boolean;true:不做任何改变,false:返回一个空的optional;
//因为阿飞2不等于阿飞,所以会返回一个空的optional
Optional<MyUser> myUser3 = myUser2.filter(user -> "阿飞2".equals(user.getName1()));
// isPresent就是判断value是不是null;我们在调用get之前,一定要先调用isPresent,因为直接如果value是null,直接调用get会报异常;
if (myUser1.isPresent()) {
MyUser value = myUser1.get();
System.out.println("optional value:" + value);
} else {
System.out.println("optional value==null");
}
// ifPresent传入一段lambda,当value!=null时,执行里面的逻辑;当当value==null时,啥都不干;
myUser2.ifPresent(value -> System.out.println("optional value:" + value));
System.out.println(myUser3);
// 输入如下:
//optional value==null
//optional value:MyUser{id='阿飞', username='123456'}
//Optional.empty
}
}
2.5、转换类
package com.fcors.fcors;
import org.junit.Test;
import java.util.Optional;
public class OptionalTest {
@Test
public void testOptional(){
Optional<MyUser> userInfoOpt = Optional.of(new MyUser("阿飞","123456"));
// 原来value的类型是UserInfo,经过map转换为Optional<String>
Optional<String> username = userInfoOpt.map(MyUser::getName1);
// 当map的入参也是一个Optional时,经过map转化后会形成Optional<Optional<String>>这种嵌套结构;但flatMap可以把这种嵌套结构打平;
Optional<Optional<String>> unFlatMap = userInfoOpt.map(user -> Optional.of(user.getName1()));
Optional<String> flatMap = userInfoOpt.flatMap(user -> Optional.of(user.getName1()));
System.out.println(username);
System.out.println(unFlatMap);
System.out.println(flatMap);
// 输出如下:
// Optional[阿飞]
// Optional[Optional[阿飞]]
// Optional[阿飞]
}
}
2.6 为空处理
- orElse(T other)
- orElseGet(Supplier<? extends T> other)
- orElseThrow(Supplier<? extends X> exceptionSupplier)
2.6.1 orElse
如果Optional中的值不为空,则返回Optional中的值,如果为空,则返回other值
/**orElse**/
String value = "2";
String orElse = Optional.ofNullable(value).orElse("1");
System.out.println(orElse); //2
String value = null;
String orElse = Optional.ofNullable(value).orElse("1");
System.out.println(orElse); //1
2.6.2 orElseGet
如果Optional中存在值,则返回值,否则返回other调用的结果
/**orElseGet**/
public static void main(String[] args) {
/**optional不为空值**/
String value = "2";
String orElse = Optional.ofNullable(value).orElseGet(OptionalTest::get);
System.out.println(orElse); // 2
/**optional空值**/
String value2 = null;
String orElse2 = Optional.ofNullable(value2).orElseGet(OptionalTest::get);
System.out.println(orElse2); // 123
}
public static String get(){
return "123";
}
2.6.3 orElseThrow
为空时抛出异常
/**orElseThrow **/
public static void main(String[] args) {
String value = null;
String orElse = Optional.ofNullable(value).orElseThrow(() -> new RuntimeException("不存在值"));
System.out.println(orElse);
}
3、实战例子
我们将一个从远程接口获取了一个用户的信息,包含家庭信息,学历信息,个人信息,然后封装成一个VO,再返回前端进行展示。
此处我们运用到知识点Builder和Optional
3.1创建家庭、学历信息、个人信息实体类
3.1.1Family
package com.fcors.fcors.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Family {
private String fatherName;
private String motherName;
}
3.1.2Education
package com.fcors.fcors.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Education {
private String education;
private String schoolName;
private Date admissionTime;
private Date graduationTime;
}
3.1.3UserInfo
package com.fcors.fcors.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
private String name;
private Integer age;
private Family family;
private Education education;
}
3.2创建UserVo
package com.fcors.fcors.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserVO {
private String username;
private Integer userAge;
private String edu;
private String school;
private Date admissionDate;
private Date graduationDate;
private String mother;
private String father;
}
单元测试例子:vo展示
@Test
public void OptionDemo1(){
/*获取UserInfo*/
UserInfo userInfo = getUser();
UserVO.UserVOBuilder userVoBuilder = UserVO.builder();
/**传统if的方式**/
if(userInfo !=null){
userVoBuilder.username(userInfo.getName())
.userAge(userInfo.getAge());
if(userInfo.getEducation() != null){
userVoBuilder.edu(userInfo.getEducation().getEducation())
.school(userInfo.getEducation().getSchoolName());
}
if(userInfo.getFamily() != null){
userVoBuilder.father(userInfo.getFamily().getFatherName())
.mother(userInfo.getFamily().getMotherName());
}
}
UserVO userVo1 = userVoBuilder.build();
/**使用optional**/
UserVO.UserVOBuilder userVoBuilder2 = UserVO.builder();
Optional.ofNullable(userInfo).ifPresent(userInfoI -> {
userVoBuilder2.username(userInfoI.getName()).userAge(userInfoI.getAge());
Optional.ofNullable(userInfoI.getFamily()).ifPresent(family -> {
userVoBuilder2.father(family.getFatherName()).mother(family.getMotherName());
});
Optional.ofNullable(userInfoI.getEducation()).ifPresent(education -> {
userVoBuilder2.edu(education.getEducation())
.school(education.getSchoolName())
.admissionDate(education.getAdmissionTime())
.graduationDate(education.getGraduationTime());
});
});
UserVO userVo2 = userVoBuilder2.build();
System.out.println(userVo1);
System.out.println(userVo2);
}
public UserInfo getUser(){
Family family = Family.builder()
.fatherName("father")
.motherName("monther")
.build();
Education education = Education.builder()
.education("本科")
.schoolName("湖南工业大学")
.admissionTime(new Date())
.graduationTime(new Date())
.build();
return UserInfo.builder()
.name("小四哥")
.age(24)
.family(family)
.education(education).build();
}
demo2:返回值
@Test
public void OptionDemo2(){
/*获取用户的毕业时间*/
UserInfo userInfo = getUser();
Date GraduationTime1= null;
Date GraduationTime2= null;
if (null != userInfo) {
if (null != userInfo.getEducation()){
GraduationTime1 = userInfo.getEducation().getGraduationTime();
}
}
GraduationTime2= Optional.ofNullable(userInfo)
.map(UserInfo::getEducation)
.map(Education::getGraduationTime)
.orElse(null);
System.out.println(GraduationTime1);
System.out.println(GraduationTime2);
}