Skip to content

Commit 4e30820

Browse files
loolygitee-org
authored andcommitted
!1287 GifCaptcha.setRepeat设置无效值的处理及GifCaptcha测试用例的补充
Merge pull request !1287 from miko/v5-dev
2 parents 416f0f3 + 79edb43 commit 4e30820

File tree

3 files changed

+264
-3
lines changed

3 files changed

+264
-3
lines changed

hutool-captcha/src/main/java/cn/hutool/captcha/GifCaptcha.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ public GifCaptcha setQuality(int quality) {
113113
* @return this
114114
*/
115115
public GifCaptcha setRepeat(int repeat) {
116-
if (repeat >= 0) {
117-
this.repeat = repeat;
118-
}
116+
this.repeat = Math.max(repeat, 0);
119117
return this;
120118
}
121119

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package cn.hutool.captcha;
2+
3+
import org.junit.jupiter.api.BeforeEach;
4+
import org.junit.jupiter.api.Test;
5+
6+
import java.awt.*;
7+
import java.io.ByteArrayOutputStream;
8+
import java.lang.reflect.Field;
9+
import java.lang.reflect.Method;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
public class GifCaptchaUtilTest {
14+
15+
private GifCaptcha captcha;
16+
17+
@BeforeEach
18+
public void setUp() {
19+
// 初始化 GifCaptcha 类的实例
20+
captcha = new GifCaptcha(200, 100, 4, 10); // width, height, codeCount, interfereCount
21+
}
22+
23+
// 使用反射调用私有方法
24+
private Object invokePrivateMethod(String methodName, Class<?>[] parameterTypes, Object[] parameters) throws Exception {
25+
Method method = GifCaptcha.class.getDeclaredMethod(methodName, parameterTypes);
26+
method.setAccessible(true); // 允许访问私有方法
27+
return method.invoke(captcha, parameters);
28+
}
29+
30+
// 测试 setQuality() 方法
31+
@Test
32+
public void testSetQuality() throws Exception {
33+
captcha.setQuality(20);
34+
// 通过反射获取 quality 字段的值并进行断言
35+
assertEquals(20, getPrivateField("quality"), "Quality 应该设置为 20");
36+
37+
captcha.setQuality(0); // 设置无效值,应该被设置为 1
38+
assertEquals(1, getPrivateField("quality"), "Quality 应该设置为 1,如果小于 1");
39+
}
40+
41+
// 测试 setRepeat() 方法
42+
@Test
43+
public void testSetRepeat() throws Exception {
44+
captcha.setRepeat(5);
45+
// 通过反射获取 repeat 字段的值并进行断言
46+
assertEquals(5, getPrivateField("repeat"), "Repeat 应该设置为 5");
47+
48+
captcha.setRepeat(-1); // 设置无效值,应该保持为 0
49+
assertEquals(0, getPrivateField("repeat"), "Repeat 应该设置为 0,如果设置了负值");
50+
}
51+
52+
// 测试 setColorRange() 方法
53+
@Test
54+
public void testSetColorRange() throws Exception {
55+
captcha.setMinColor(100).setMaxColor(200);
56+
// 通过反射获取 minColor 和 maxColor 字段的值并进行断言
57+
assertEquals(100, getPrivateField("minColor"), "Min color 应该设置为 100");
58+
assertEquals(200, getPrivateField("maxColor"), "Max color 应该设置为 200");
59+
}
60+
61+
// 测试生成验证码图像的方法 createCode()
62+
@Test
63+
public void testCreateCode() throws Exception {
64+
captcha.createCode();
65+
byte[] imageBytes = captcha.getImageBytes();
66+
67+
// 检查生成的图片字节是否不为 null 或空
68+
assertNotNull(imageBytes, "生成的图片字节不应该为 null");
69+
assertTrue(imageBytes.length > 0, "生成的图片字节不应该为空");
70+
71+
// 可选:你也可以通过解码图片字节,检查它是否是有效的 GIF 格式
72+
ByteArrayOutputStream out = new ByteArrayOutputStream();
73+
out.write(imageBytes);
74+
75+
// 解码图片检查它是否为有效的 GIF(假设你有库可以解码 GIF)
76+
// ImageIO.read(new ByteArrayInputStream(imageBytes)); // 可以取消注释来检查它是否是有效的 GIF
77+
}
78+
79+
// 测试 graphicsImage() 方法
80+
@Test
81+
public void testGraphicsImage() throws Exception {
82+
char[] chars = new char[]{'A', 'B', 'C', 'D'};
83+
Color[] colors = new Color[]{
84+
Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW
85+
};
86+
87+
// 使用反射调用 private 方法 graphicsImage
88+
Object result = invokePrivateMethod("graphicsImage", new Class[]{char[].class, Color[].class, char[].class, int.class}, new Object[]{chars, colors, chars, 0});
89+
90+
assertNotNull(result, "生成的图片不应该为 null");
91+
assertTrue(result instanceof java.awt.image.BufferedImage, "返回的结果应该是 BufferedImage 类型");
92+
}
93+
94+
// 测试 getRandomColor() 方法
95+
@Test
96+
public void testRandomColor() throws Exception {
97+
// 使用反射调用 private 方法 getRandomColor
98+
Object result = invokePrivateMethod("getRandomColor", new Class[]{int.class, int.class}, new Object[]{0, 255});
99+
100+
assertNotNull(result, "生成的颜色不应该为 null");
101+
assertTrue(result instanceof Color, "返回的结果应该是 Color 类型");
102+
103+
Color color = (Color) result;
104+
assertTrue(color.getRed() >= 0 && color.getRed() <= 255, "颜色的红色分量应该在 0 到 255 之间");
105+
assertTrue(color.getGreen() >= 0 && color.getGreen() <= 255, "颜色的绿色分量应该在 0 到 255 之间");
106+
assertTrue(color.getBlue() >= 0 && color.getBlue() <= 255, "颜色的蓝色分量应该在 0 到 255 之间");
107+
}
108+
109+
// 辅助方法:通过反射获取私有字段的值
110+
private Object getPrivateField(String fieldName) throws NoSuchFieldException, IllegalAccessException {
111+
Field field = GifCaptcha.class.getDeclaredField(fieldName);
112+
field.setAccessible(true); // 允许访问私有字段
113+
return field.get(captcha);
114+
}
115+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package cn.hutool.captcha;
2+
import cn.hutool.captcha.ShearCaptcha;
3+
import cn.hutool.captcha.generator.RandomGenerator;
4+
import cn.hutool.core.img.GraphicsUtil;
5+
import cn.hutool.core.img.ImgUtil;
6+
import cn.hutool.core.util.RandomUtil;
7+
import org.junit.jupiter.api.BeforeEach;
8+
import org.junit.jupiter.api.Test;
9+
10+
import java.awt.*;
11+
import java.awt.image.BufferedImage;
12+
import java.lang.reflect.Method;
13+
14+
import static org.junit.jupiter.api.Assertions.*;
15+
16+
public class ShearCaptchaTest {
17+
18+
private ShearCaptcha captcha;
19+
20+
@BeforeEach
21+
public void setUp() {
22+
// 初始化 ShearCaptcha 实例
23+
captcha = new ShearCaptcha(200, 100);
24+
}
25+
26+
// 测试构造函数和基本功能
27+
@Test
28+
public void testConstructor() {
29+
assertNotNull(captcha, "Captcha 实例应该被成功创建");
30+
}
31+
32+
// 测试生成验证码图片的功能
33+
@Test
34+
public void testCreateImage() {
35+
String code = "ABCD";
36+
Image image = captcha.createImage(code);
37+
assertNotNull(image, "验证码图片不应该为 null");
38+
assertTrue(image instanceof BufferedImage, "生成的图片应该是 BufferedImage 类型");
39+
40+
// 可选:进一步测试图像的内容
41+
BufferedImage bufferedImage = (BufferedImage) image;
42+
assertEquals(200, bufferedImage.getWidth(), "图像宽度应该为 200");
43+
assertEquals(100, bufferedImage.getHeight(), "图像高度应该为 100");
44+
}
45+
46+
// 测试绘制字符串的方法
47+
@Test
48+
public void testDrawString() throws Exception {
49+
String code = "ABCD";
50+
Method drawStringMethod = ShearCaptcha.class.getDeclaredMethod("drawString", Graphics2D.class, String.class);
51+
drawStringMethod.setAccessible(true);
52+
53+
Graphics2D g2d = (Graphics2D) new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB).getGraphics();
54+
drawStringMethod.invoke(captcha, g2d, code);
55+
56+
assertNotNull(g2d, "Graphics2D 对象不应该为 null");
57+
assertTrue(g2d.getRenderingHints().containsKey(RenderingHints.KEY_ANTIALIASING), "应该启用抗锯齿");
58+
}
59+
60+
// 测试 shear() 方法
61+
@Test
62+
public void testShear() throws Exception {
63+
// 使用反射测试 shear 方法
64+
Method shearMethod = ShearCaptcha.class.getDeclaredMethod("shear", Graphics.class, int.class, int.class, Color.class);
65+
shearMethod.setAccessible(true);
66+
67+
Graphics g = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB).getGraphics();
68+
shearMethod.invoke(captcha, g, 200, 100, Color.WHITE);
69+
70+
// 假设没有明显的错误输出,认为测试通过
71+
assertNotNull(g, "Graphics 对象不应该为 null");
72+
}
73+
74+
// 测试 shearX() 方法
75+
@Test
76+
public void testShearX() throws Exception {
77+
// 使用反射测试 shearX 方法
78+
Method shearXMethod = ShearCaptcha.class.getDeclaredMethod("shearX", Graphics.class, int.class, int.class, Color.class);
79+
shearXMethod.setAccessible(true);
80+
81+
Graphics g = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB).getGraphics();
82+
shearXMethod.invoke(captcha, g, 200, 100, Color.RED);
83+
84+
// 假设没有明显的错误输出,认为测试通过
85+
assertNotNull(g, "Graphics 对象不应该为 null");
86+
}
87+
88+
// 测试 shearY() 方法
89+
@Test
90+
public void testShearY() throws Exception {
91+
// 使用反射测试 shearY 方法
92+
Method shearYMethod = ShearCaptcha.class.getDeclaredMethod("shearY", Graphics.class, int.class, int.class, Color.class);
93+
shearYMethod.setAccessible(true);
94+
95+
Graphics g = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB).getGraphics();
96+
shearYMethod.invoke(captcha, g, 200, 100, Color.BLUE);
97+
98+
// 假设没有明显的错误输出,认为测试通过
99+
assertNotNull(g, "Graphics 对象不应该为 null");
100+
}
101+
102+
// 测试 drawInterfere() 方法
103+
@Test
104+
public void testDrawInterfere() throws Exception {
105+
// 使用反射测试 drawInterfere 方法
106+
Method drawInterfereMethod = ShearCaptcha.class.getDeclaredMethod("drawInterfere", Graphics.class, int.class, int.class, int.class, int.class, int.class, Color.class);
107+
drawInterfereMethod.setAccessible(true);
108+
109+
Graphics g = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB).getGraphics();
110+
drawInterfereMethod.invoke(captcha, g, 0, 0, 200, 100, 4, Color.GREEN);
111+
112+
// 假设没有明显的错误输出,认为测试通过
113+
assertNotNull(g, "Graphics 对象不应该为 null");
114+
}
115+
116+
// 测试验证码生成时的干扰线
117+
@Test
118+
public void testDrawInterfereLines() {
119+
// 设置干扰线数量
120+
captcha = new ShearCaptcha(200, 100, 4);
121+
Image image = captcha.createImage("ABCD");
122+
123+
// 检查图像内容,判断干扰线是否正确绘制
124+
assertNotNull(image, "生成的验证码图片不应该为空");
125+
}
126+
127+
// 测试验证码的尺寸
128+
@Test
129+
public void testCaptchaSize() {
130+
captcha = new ShearCaptcha(300, 150);
131+
132+
String code = "XYZ";
133+
Image image = captcha.createImage(code);
134+
135+
BufferedImage bufferedImage = (BufferedImage) image;
136+
assertEquals(300, bufferedImage.getWidth(), "图像宽度应该为 300");
137+
assertEquals(150, bufferedImage.getHeight(), "图像高度应该为 150");
138+
}
139+
140+
// 测试生成随机验证码字符
141+
@Test
142+
public void testRandomGenerator() {
143+
RandomGenerator randomGenerator = new RandomGenerator(4);
144+
String code = randomGenerator.generate();
145+
assertNotNull(code, "生成的验证码字符不应该为 null");
146+
assertEquals(4, code.length(), "验证码字符长度应该为 4");
147+
}
148+
}

0 commit comments

Comments
 (0)