完善单元测试

This commit is contained in:
click33
2022-09-02 21:02:39 +08:00
parent 285dacf06c
commit a673bfb550
18 changed files with 545 additions and 29 deletions

View File

@@ -71,7 +71,8 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>${argLine} -Xms256m -Xmx2048m</argLine>
<!-- 命令行执行 mvn test 时默认字符集为GBK与项目设置的utf-8造成冲突所以这里需要指定字符集为utf-8 -->
<argLine>${argLine} -Xms256m -Xmx2048m -Dfile.encoding=utf-8</argLine>
<forkCount>1</forkCount>
<runOrder>random</runOrder>
</configuration>

View File

@@ -17,6 +17,7 @@ public class SaTokenDaoTest {
SaTokenDao dao = new SaTokenDaoDefaultImpl();
// 字符串存取
@Test
public void get() {
dao.set("name", "zhangsan", 60);
@@ -34,6 +35,7 @@ public class SaTokenDaoTest {
Assertions.assertEquals(dao.get("name"), null);
}
// 对象存取
@Test
public void getObject() {
dao.setObject("name", "zhangsan", 60);
@@ -50,6 +52,7 @@ public class SaTokenDaoTest {
Assertions.assertEquals(dao.getObject("name"), null);
}
// SaSession 存取
@Test
public void getSession() {
SaSession session = new SaSession("session-1001");
@@ -69,4 +72,68 @@ public class SaTokenDaoTest {
Assertions.assertEquals(dao.getSession("session-1001"), null);
}
// 测试永久有效期的写值改值
@Test
public void testUpdate() {
// ----------- 字符串 相关
// 永久有效
dao.set("age", "20", -1);
Assertions.assertEquals(dao.get("age"), "20");
Assertions.assertEquals(dao.getTimeout("age"), SaTokenDao.NEVER_EXPIRE);
// 修改值
dao.update("age", "22");
Assertions.assertEquals(dao.get("age"), "22");
// 有效期应该不变,还是永久
Assertions.assertEquals(dao.getTimeout("age"), SaTokenDao.NEVER_EXPIRE);
// ----------- Session 相关
// 永久有效
SaSession session = new SaSession("session-1001");
dao.setSession(session, -1);
Assertions.assertEquals(dao.getSession("session-1001").getId(), session.getId());
Assertions.assertEquals(dao.getSessionTimeout("session-1001"), SaTokenDao.NEVER_EXPIRE);
// 修改值
dao.updateSession(session);
Assertions.assertEquals(dao.getSession("session-1001").getId(), session.getId());
// 有效期应该不变,还是永久
Assertions.assertEquals(dao.getSessionTimeout("session-1001"), SaTokenDao.NEVER_EXPIRE);
// ----------- 无效update
dao.update("mid", "zhang");
Assertions.assertNull(dao.get("mid"));
}
// timeout为0或者小于-2时不写入
@Test
public void test0Timeout() {
// ----------- 字符串 相关
// 字符串 0 和 <-2
dao.set("avatar", "1.jpg", 0);
Assertions.assertNull(dao.get("avatar"));
dao.set("avatar", "1.jpg", -9);
Assertions.assertNull(dao.get("avatar"));
// ----------- Session 相关
// Session 0 和 <-2
SaSession session = new SaSession("session-1001");
dao.setSession(session, 0);
Assertions.assertNull(dao.getSession("session-1001"));
dao.setSession(session, -9);
Assertions.assertNull(dao.getSession("session-1001"));
}
// TO-DO 和时间相关的测试
}

View File

@@ -31,4 +31,22 @@ public class IsRunFunctionTest {
Assertions.assertEquals(obj.count, 2);
}
@Test
public void test2() {
class TempClass{
int count = 1;
}
TempClass obj = new TempClass();
IsRunFunction fun = new IsRunFunction(false);
fun.exe(()->{
obj.count = 2;
}).noExe(()->{
obj.count = 3;
});
Assertions.assertEquals(obj.count, 3);
}
}

View File

@@ -0,0 +1,31 @@
package cn.dev33.satoken.core.json;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import cn.dev33.satoken.exception.ApiDisabledException;
import cn.dev33.satoken.json.SaJsonTemplateDefaultImpl;
import cn.dev33.satoken.util.SoMap;
/**
* json默认实现类测试
*
* @author kong
* @since: 2022-9-1
*/
public class SaJsonTemplateDefaultImplTest {
@Test
public void testSaJsonTemplateDefaultImpl() {
SaJsonTemplateDefaultImpl saJsonTemplate = new SaJsonTemplateDefaultImpl();
// API 禁用
Assertions.assertThrows(ApiDisabledException.class, () -> {
saJsonTemplate.parseJsonToMap("{}");
});
// API 禁用
Assertions.assertThrows(ApiDisabledException.class, () -> {
saJsonTemplate.toJsonString(SoMap.getSoMap("name", "zhangsan"));
});
}
}

View File

@@ -0,0 +1,47 @@
package cn.dev33.satoken.core.sign;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.util.SoMap;
/**
* API 接口签名测试
*
* @author kong
* @since: 2022-9-2
*/
public class SaSignTemplateTest {
String key = "SwqFmsKxcbq23";
// 连接参数列表
@Test
public void testJoinParams() {
SoMap map = SoMap.getSoMap()
.set("name", "zhang")
.set("age", 18)
.set("sex", "");
String str = SaManager.getSaSignTemplate().joinParams(map);
// 按照音序排列
Assertions.assertEquals(str, "age=18&name=zhang&sex=女");
}
// 给参数签名
@Test
public void testCreateSign() {
SoMap map = SoMap.getSoMap()
.set("name", "zhang")
.set("age", 18)
.set("sex", "");
String sign = SaManager.getSaSignTemplate().createSign(map, key);
Assertions.assertEquals(sign, "6f5e844a53e74363c2f6b24f64c4f0ff");
// 多次签名,结果一致
String sign2 = SaManager.getSaSignTemplate().createSign(map, key);
Assertions.assertEquals(sign, sign2);
}
}

View File

@@ -0,0 +1,52 @@
package cn.dev33.satoken.core.temp;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.temp.SaTempUtil;
/**
* 临时Token模块测试
*
* @author kong
* @since: 2022-9-1
*/
public class SaTempTest {
// 测试临时Token认证模块
@Test
public void testSaTemp() {
SaTokenDao dao = SaManager.getSaTokenDao();
// 生成token
String token = SaTempUtil.createToken("group-1014", 200);
Assertions.assertNotNull(token);
// 解析token
String value = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value, "group-1014");
Assertions.assertEquals(dao.getObject("satoken:temp-token:" + token), "group-1014");
// 默认类型
Object value3 = SaTempUtil.parseToken(token);
Assertions.assertEquals(value3, "group-1014");
// 过期时间
long timeout = SaTempUtil.getTimeout(token);
Assertions.assertTrue(timeout > 195);
// 回收token
SaTempUtil.deleteToken(token);
String value2 = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value2, null);
Assertions.assertEquals(dao.getObject("satoken:temp-token:" + token), null);
}
@Test
public void testSaTemp2() {
// 秘钥默认为null
String jwtSecretKey = SaManager.getSaTemp().getJwtSecretKey();
Assertions.assertEquals(jwtSecretKey, null);
}
}

View File

@@ -34,6 +34,7 @@ public class SaResultTest {
// 自定义写值取值
res.set("age", 18);
Assertions.assertEquals(res.get("age"), 18);
Assertions.assertEquals(res.get("age", String.class), "18");
Assertions.assertEquals(res.getOrDefault("age", 20), 18);
Assertions.assertEquals(res.getOrDefault("age2", 20), 20);
}

View File

@@ -0,0 +1,83 @@
package cn.dev33.satoken.integrate.annotation;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.dev33.satoken.annotation.SaCheckBasic;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaCheckSafe;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
/**
* 测试注解用的Controller
*
* @author kong
* @since: 2022-9-2
*/
@RestController
@RequestMapping("/at/")
public class SaAnnotationController {
// ------------------------ 简单测试
// 登录
@RequestMapping("login")
public SaResult login(long id) {
StpUtil.login(id);
return SaResult.ok().set("token", StpUtil.getTokenValue());
}
// 登录校验
@SaCheckLogin
@RequestMapping("checkLogin")
public SaResult checkLogin() {
return SaResult.ok();
}
// 角色校验
@SaCheckRole("admin")
@RequestMapping("checkRole")
public SaResult checkRole() {
return SaResult.ok();
}
// 权限校验
@SaCheckPermission("art-add")
@RequestMapping("checkPermission")
public SaResult checkPermission() {
return SaResult.ok();
}
// 权限校验 or 角色校验
@SaCheckPermission(value = "art-add2", orRole = "admin")
@RequestMapping("checkPermission2")
public SaResult checkPermission2() {
return SaResult.ok();
}
// Http Basic 认证
@SaCheckBasic
@RequestMapping("checkBasic")
public SaResult checkBasic() {
return SaResult.ok();
}
// 开启二级认证
@RequestMapping("openSafe")
public SaResult openSafe(long id) {
StpUtil.openSafe(120);
return SaResult.ok();
}
// 二级认证校验
@SaCheckSafe
@RequestMapping("checkSafe")
public SaResult checkSafe() {
return SaResult.ok();
}
}

View File

@@ -0,0 +1,118 @@
package cn.dev33.satoken.integrate.annotation;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.integrate.StartUpApplication;
import cn.dev33.satoken.util.SaResult;
/**
* 注解鉴权测试
*
* @author Auster
*
*/
@SpringBootTest(classes = StartUpApplication.class)
public class SaAnnotationControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mvc;
// 每个方法前执行
@BeforeEach
public void before() {
mvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
// 校验通过的情况
@Test
public void testPassing() {
// 登录拿到Token
SaResult res = request("/at/login?id=10001");
String satoken = res.get("token", String.class);
Assertions.assertNotNull(satoken);
// 登录校验,通过
SaResult res2 = request("/at/checkLogin?satoken=" + satoken);
Assertions.assertEquals(res2.getCode(), 200);
// 角色校验,通过
SaResult res3 = request("/at/checkRole?satoken=" + satoken);
Assertions.assertEquals(res3.getCode(), 200);
// 权限校验,通过
SaResult res4 = request("/at/checkPermission?satoken=" + satoken);
Assertions.assertEquals(res4.getCode(), 200);
// 权限校验or角色校验通过
SaResult res5 = request("/at/checkPermission2?satoken=" + satoken);
Assertions.assertEquals(res5.getCode(), 200);
}
// 校验不通过的情况
@Test
public void testNotPassing() {
// 登录拿到Token
SaResult res = request("/at/login?id=10002");
String satoken = res.get("token", String.class);
Assertions.assertNotNull(satoken);
// 登录校验,不通过
SaResult res2 = request("/at/checkLogin");
Assertions.assertEquals(res2.getCode(), 401);
// 角色校验,不通过
SaResult res3 = request("/at/checkRole?satoken=" + satoken);
Assertions.assertEquals(res3.getCode(), 402);
// 权限校验,不通过
SaResult res4 = request("/at/checkPermission?satoken=" + satoken);
Assertions.assertEquals(res4.getCode(), 403);
// 权限校验or角色校验不通过
SaResult res5 = request("/at/checkPermission2?satoken=" + satoken);
Assertions.assertEquals(res5.getCode(), 403);
}
// 封装请求
private SaResult request(String path) {
try {
// 发请求
MvcResult mvcResult = mvc.perform(
MockMvcRequestBuilders.post(path)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.accept(MediaType.APPLICATION_PROBLEM_JSON)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
// 转 Map
String content = mvcResult.getResponse().getContentAsString();
Map<String, Object> map = SaManager.getSaJsonTemplate().parseJsonToMap(content);
// 转 SaResult 对象
return new SaResult().setMap(map);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,37 @@
package cn.dev33.satoken.integrate.configure;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.util.SaResult;
/**
* 全局异常处理
* @author kong
*
*/
@RestControllerAdvice
public class HandlerException {
// 未登录异常code=401
@ExceptionHandler(NotLoginException.class)
public SaResult handlerNotLoginException(NotLoginException e) {
return SaResult.error().setCode(401);
}
// 缺少角色异常code=402
@ExceptionHandler(NotRoleException.class)
public SaResult handlerNotRoleException(NotRoleException e) {
return SaResult.error().setCode(402);
}
// 缺少权限异常code=403
@ExceptionHandler(NotPermissionException.class)
public SaResult handlerNotPermissionException(NotPermissionException e) {
return SaResult.error().setCode(403);
}
}

View File

@@ -0,0 +1,24 @@
package cn.dev33.satoken.integrate.configure;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cn.dev33.satoken.interceptor.SaInterceptor;
/**
* Sa-Token 相关配置类
*
* @author kong
* @since: 2022-9-2
*/
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,打开注解式鉴权功能
registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
}
}

View File

@@ -0,0 +1,46 @@
package cn.dev33.satoken.integrate.configure;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.util.SaFoxUtil;
/**
* 自定义权限验证接口扩展
*
* @author kong
*
*/
@Component
public class StpInterfaceImpl implements StpInterface {
/**
* 返回一个账号所拥有的权限码集合
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
int id = SaFoxUtil.getValueByType(loginId, int.class);
if(id == 10001) {
return Arrays.asList("user*", "art-add", "art-delete", "art-update", "art-get");
} else {
return null;
}
}
/**
* 返回一个账号所拥有的角色标识集合
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
int id = SaFoxUtil.getValueByType(loginId, int.class);
if(id == 10001) {
return Arrays.asList("admin", "super-admin");
} else {
return null;
}
}
}

View File

@@ -1,4 +1,4 @@
package cn.dev33.satoken.integrate;
package cn.dev33.satoken.integrate.login;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -1,4 +1,4 @@
package cn.dev33.satoken.integrate;
package cn.dev33.satoken.integrate.login;
import java.util.Map;
@@ -15,7 +15,8 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import cn.dev33.satoken.integrate.util.SoMap;
import cn.dev33.satoken.integrate.StartUpApplication;
import cn.dev33.satoken.util.SoMap;
/**
* Sa-Token 登录API测试

View File

@@ -16,7 +16,6 @@ import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.temp.SaTempUtil;
import cn.dev33.satoken.util.SaTokenConsts;
/**
@@ -320,29 +319,6 @@ public class BasicsTest {
Assertions.assertTrue(list.size() >= 5);
}
// 测试临时Token认证模块
@Test
public void testSaTemp() {
// 生成token
String token = SaTempUtil.createToken("group-1014", 200);
Assertions.assertNotNull(token);
// 解析token
String value = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value, "group-1014");
Assertions.assertEquals(dao.getObject("satoken:temp-token:" + token), "group-1014");
// 过期时间
long timeout = SaTempUtil.getTimeout(token);
Assertions.assertTrue(timeout > 195);
// 回收token
SaTempUtil.deleteToken(token);
String value2 = SaTempUtil.parseToken(token, String.class);
Assertions.assertEquals(value2, null);
Assertions.assertEquals(dao.getObject("satoken:temp-token:" + token), null);
}
// 测试:二级认证
@Test
public void testSafe() {

View File

@@ -1,4 +1,4 @@
package cn.dev33.satoken.integrate.util;
package cn.dev33.satoken.util;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;