JUnit测试中成员变量cc值异常求助:预期值与实际值不符
问题分析与解决方案
让我来帮你拆解这个问题:你的断言错误既不是因为重复使用端口,也不是JUnit测试方法之间的cc变量互相干扰——JUnit 4及以上版本默认会为每个@Test方法创建一个独立的测试类实例,所以两个测试里的cc变量是完全隔离的,第二个测试中对cc的赋值肯定是有效的。
真正的问题出在GreenMail没有在测试之间重置状态:
- 第一个测试
testSendMailWithMissingData发送了一封没有CC的邮件,GreenMail会把这封邮件存在收件箱里 - 第二个测试
testSendMailWIthData执行时,你没有清空之前的收件箱,调用greenMail.getReceivedMessages()会返回所有收到的邮件(包括第一个测试的那封) - 你直接取了数组的第一个元素
emails2[0],这其实是第一封没有CC的邮件,自然会断言失败
另外提一句,你的第二个测试方法名有个小拼写错误(WIth应该是With),不过这不会影响代码执行~
具体解决步骤
1. 用@Before/@After隔离GreenMail状态
在每个测试方法执行前后重置GreenMail的收件箱,确保测试之间完全独立:
@Before public void setup() { // 清空收件箱,重置所有邮件状态 greenMail.reset(); } @After public void teardown() { // 可选:如果测试结束后需要关闭GreenMail,加这行 greenMail.stop(); }
2. 先验证邮件数量(推荐)
在断言CC字段之前,先检查收到的邮件数量是否符合预期,避免取错邮件:
// 在第二个测试里 MimeMessage[] emails2 = greenMail.getReceivedMessages(); // 确认只收到当前测试发送的1封邮件 assertEquals(1, emails2.length); // 再断言CC字段 assertEquals(cc, InternetAddress.toString(emails2[0].getRecipients(Message.RecipientType.CC)));
3. 优化变量定义(可选但更清晰)
虽然不是问题根源,但建议不要用类级别的公共变量传递测试数据,直接在测试方法里定义局部变量会更直观,减少混淆:
// 删掉类里的public String cc = ""; @Test public void testSendMailWithData() throws MessagingException { String sender = "test@test.com"; String receiver = "receiver@receiver.com"; String subject = "test_subject"; String content = "test_content"; String cc = "ccaddress@cc.com"; // 局部变量,只在当前测试生效 javaMailSenderImpl.setPort(greenMail.getSmtp().getPort()); iMailService.sendMail(sender, receiver, subject, content, cc); // ... 后续断言逻辑 }
补充说明
- 端口复用没问题:两个测试都用GreenMail的SMTP端口是正确的,GreenMail在测试运行期间会保持端口开放,所有测试都应该连接这个端口发邮件。
- JUnit的隔离机制:JUnit会为每个测试方法创建新的测试类实例,所以实例变量不会在测试之间共享,你完全不用担心
cc变量被前一个测试覆盖。
内容的提问来源于stack exchange,提问作者lpkej
相关产品推荐
相关产品推荐

