管理检查 JUnit 中抛出的 ExpectedException 的规则
Rules that govern Checking for ExpectedException thrown in JUnit
我的任务是计算给定的两个字符串中不匹配(不同字符)的数量。虽然;有两个条件需要满足。
If the lengths of given two Strings are not same; throw an Exception with appropriate message.
If only one input String is provided; throw an Exception with appropriate message.
我的解决方案:
class Hamming {
private final String leftString;
private final String rightString;
public Hamming(String leftString, String rightString) {
this.leftString = leftString;
this.rightString = rightString;
}
public int getHammingDistance() {
int hammingDistance = 0;
int secondCharIndex = 0;
if (leftString.length() == 0 && rightString.length() != 0)
throw new IllegalArgumentException("left string must not be empty.");
if (rightString.length() == 0 && leftString.length() != 0)
throw new IllegalArgumentException("right string must not be empty.");
if (leftString.length() != rightString.length())
throw new IllegalArgumentException("left and right string must be of equal length.");
for (char ch : leftString.toCharArray()) {
if (ch != rightString.charAt(secondCharIndex)) hammingDistance++;
secondCharIndex++;
}
return hammingDistance;
}
}
现在,当我运行直接使用这个解决方案时;它按预期工作。您可以找到上述代码的 运行 示例 here.
当我尝试 运行 使用 Junit 测试覆盖率 的相同代码时;相同的代码无法通过所有涉及异常的测试用例。下面是我的 HammingTest.java
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import org.junit.Ignore;
import org.junit.Test;
public class HammingTest {
@Test
public void testNoDistanceBetweenEmptyStrings() {
assertEquals(0, new Hamming("", "").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testNoDistanceBetweenShortIdenticalStrings() {
assertEquals(0, new Hamming("A", "A").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testCompleteDistanceInSingleLetterDifferentStrings() {
assertEquals(1, new Hamming("G", "T").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testDistanceInLongIdenticalStrings() {
assertEquals(0, new Hamming("GGACTGAAATCTG", "GGACTGAAATCTG").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testDistanceInLongDifferentStrings() {
assertEquals(9, new Hamming("GGACGGATTCTG", "AGGACGGATTCT").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testValidatesFirstStringNotLonger() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("AATG", "AAA"));
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
// @Ignore("Remove to run test")
@Test
public void testValidatesSecondStringNotLonger() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("ATA", "AGTG"));
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
// @Ignore("Remove to run test")
@Test
public void testDisallowLeftEmptyString() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("", "G"));
assertThat(expected)
.hasMessage("left string must not be empty.");
}
// @Ignore("Remove to run test")
@Test
public void testDisallowRightEmptyString() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("G", ""));
assertThat(expected)
.hasMessage("right string must not be empty.");
}
}
我将该项目用作 gradle 项目。 因此生成的报告显示了以下问题:
是什么解决了我的问题:
工作久了;当我最终尝试 将异常抛出条件放入 Constructor 时;它解决了我的问题。每个测试用例都通过了。像这样的东西:
public Hamming(String leftString, String rightString) {
if (leftString.length() == 0 && rightString.length() != 0) {
throw new IllegalArgumentException("left string must not be empty.");
} else if (rightString.length() == 0 && leftString.length() != 0) {
throw new IllegalArgumentException("right string must not be empty.");
} else if (leftString.length() != rightString.length()) {
throw new IllegalArgumentException("leftString and rightString must be of equal length.");
}
this.leftSting = leftString;
this.rightString = rightString;
}
我的疑惑是什么:
- 为什么将异常抛出条件放在构造函数中的解决方案有效?
- 当我试图将异常抛出条件放入
getHamming()
方法时;为什么测试失败了?
- 当我运行使用前面提到的相同
Hamming
class 而没有使用 JUnit 时;它按预期工作。为什么会这样?
任何帮助都会有所帮助。
您错过了 getHammingDistance()
电话,这就是您的测试用例失败的原因。让我们来一个测试用例,看看为什么。
@Test
public void testValidatesFirstStringNotLonger() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("AATG", "AAA"));
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
第一个 assertThrows
检查 new Hamming("AATG", "AAA")
是否因 IllegalArgumentException
而失败。由于异常是在方法 getHammingDistance()
中引发的,因此断言失败。
这会奏效:
@Test
public void testValidatesFirstStringNotLonger() {
Hamming hamming = new Hamming("AATG", "AAA");
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> hamming.getHammingDistance());
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
我的任务是计算给定的两个字符串中不匹配(不同字符)的数量。虽然;有两个条件需要满足。
If the lengths of given two Strings are not same; throw an Exception with appropriate message.
If only one input String is provided; throw an Exception with appropriate message.
我的解决方案:
class Hamming {
private final String leftString;
private final String rightString;
public Hamming(String leftString, String rightString) {
this.leftString = leftString;
this.rightString = rightString;
}
public int getHammingDistance() {
int hammingDistance = 0;
int secondCharIndex = 0;
if (leftString.length() == 0 && rightString.length() != 0)
throw new IllegalArgumentException("left string must not be empty.");
if (rightString.length() == 0 && leftString.length() != 0)
throw new IllegalArgumentException("right string must not be empty.");
if (leftString.length() != rightString.length())
throw new IllegalArgumentException("left and right string must be of equal length.");
for (char ch : leftString.toCharArray()) {
if (ch != rightString.charAt(secondCharIndex)) hammingDistance++;
secondCharIndex++;
}
return hammingDistance;
}
}
现在,当我运行直接使用这个解决方案时;它按预期工作。您可以找到上述代码的 运行 示例 here.
当我尝试 运行 使用 Junit 测试覆盖率 的相同代码时;相同的代码无法通过所有涉及异常的测试用例。下面是我的 HammingTest.java
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import org.junit.Ignore;
import org.junit.Test;
public class HammingTest {
@Test
public void testNoDistanceBetweenEmptyStrings() {
assertEquals(0, new Hamming("", "").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testNoDistanceBetweenShortIdenticalStrings() {
assertEquals(0, new Hamming("A", "A").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testCompleteDistanceInSingleLetterDifferentStrings() {
assertEquals(1, new Hamming("G", "T").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testDistanceInLongIdenticalStrings() {
assertEquals(0, new Hamming("GGACTGAAATCTG", "GGACTGAAATCTG").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testDistanceInLongDifferentStrings() {
assertEquals(9, new Hamming("GGACGGATTCTG", "AGGACGGATTCT").getHammingDistance());
}
// @Ignore("Remove to run test")
@Test
public void testValidatesFirstStringNotLonger() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("AATG", "AAA"));
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
// @Ignore("Remove to run test")
@Test
public void testValidatesSecondStringNotLonger() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("ATA", "AGTG"));
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
// @Ignore("Remove to run test")
@Test
public void testDisallowLeftEmptyString() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("", "G"));
assertThat(expected)
.hasMessage("left string must not be empty.");
}
// @Ignore("Remove to run test")
@Test
public void testDisallowRightEmptyString() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("G", ""));
assertThat(expected)
.hasMessage("right string must not be empty.");
}
}
我将该项目用作 gradle 项目。 因此生成的报告显示了以下问题:
是什么解决了我的问题:
工作久了;当我最终尝试 将异常抛出条件放入 Constructor 时;它解决了我的问题。每个测试用例都通过了。像这样的东西:
public Hamming(String leftString, String rightString) {
if (leftString.length() == 0 && rightString.length() != 0) {
throw new IllegalArgumentException("left string must not be empty.");
} else if (rightString.length() == 0 && leftString.length() != 0) {
throw new IllegalArgumentException("right string must not be empty.");
} else if (leftString.length() != rightString.length()) {
throw new IllegalArgumentException("leftString and rightString must be of equal length.");
}
this.leftSting = leftString;
this.rightString = rightString;
}
我的疑惑是什么:
- 为什么将异常抛出条件放在构造函数中的解决方案有效?
- 当我试图将异常抛出条件放入
getHamming()
方法时;为什么测试失败了? - 当我运行使用前面提到的相同
Hamming
class 而没有使用 JUnit 时;它按预期工作。为什么会这样?
任何帮助都会有所帮助。
您错过了 getHammingDistance()
电话,这就是您的测试用例失败的原因。让我们来一个测试用例,看看为什么。
@Test
public void testValidatesFirstStringNotLonger() {
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> new Hamming("AATG", "AAA"));
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}
第一个 assertThrows
检查 new Hamming("AATG", "AAA")
是否因 IllegalArgumentException
而失败。由于异常是在方法 getHammingDistance()
中引发的,因此断言失败。
这会奏效:
@Test
public void testValidatesFirstStringNotLonger() {
Hamming hamming = new Hamming("AATG", "AAA");
IllegalArgumentException expected =
assertThrows(
IllegalArgumentException.class,
() -> hamming.getHammingDistance());
assertThat(expected)
.hasMessage("left and right string must be of equal length.");
}