我目前正在学习Java。我为抛出异常进行了单元测试。我跑了单元测试但失败了。对此有何看法?
这是我的代码
public Card(int rank, int suit) throws SuitOutOfRangeException, RankOutOfRangeException {
// TODO: Re-write this Constructor to throw exceptions
try {
if (suit > 4 || suit < 0) {
throw new SuitOutOfRangeException();
}
this.suit = suit % 4;
} catch (SuitOutOfRangeException ex) {
System.out.println("Your input value for suit is out of the specified range");
}
try {
if (rank > 12 || rank < 0) {
throw new RankOutOfRangeException();
}
this.rank = rank % 13;
} catch (RankOutOfRangeException ex) {
System.out.println("Your input value for rank is out of the specified range");
}
}
部分单元测试如下:
@Test
public void testConstructorShouldThrowRankOutOfRangeException() {
boolean expected = true;
boolean actual = false;
try {
Card c = new Card(100,1);
actual = false;
} catch (SuitOutOfRangeException ex) {
actual = false;
} catch (RankOutOfRangeException ex) {
actual = true;
}
assertEquals(expected,actual);
}
解决方案是
public Card(int rank, int suit ) throws SuitOutOfRangeException, RankOutOfRangeException {
if (rank <0 || rank > 12) throw new RankOutOfRangeException();
if (suit <0 || suit >3) throw new SuitOutOfRangeException();
this.suit = suit % 4;
this.rank = rank % 13;
}
答案 0 :(得分:1)
让我们对您的代码提供一些更一般的反馈;也应该回答你的某些不清楚的问题&#34;我该怎么做&#34;问题
首先,抛出异常并在构造函数中捕获它有绝对没有意义。减少到:
public Card(int rank, int suit) { // please note: no checked exceptions!
checkRank(rank);
checkSuit(suit);
this.suit = ...
使用只检查和抛出的检查方法,例如
private void checkSuit(int suit) {
if (suit < 0) throw new SuitOutOfRangeException("suit must not be negative: " + suit);
...
重点是:您希望将代码放入非常小的方法中。这种方法只有一个责任(例如:检查传入的套装是否有效范围)。而且:当你抛出异常时,你会包含以后需要的信息来理解你的失败。
要测试这样的东西,你去:
@Test(expected=SuitOutOfRangeException.class)
public void testNegativeSuit() {
new Card(1, -1);
}
那就是它。印刷品和布尔都没有这种情况。所有这些都是浪费,没有任何有意义的东西;既不符合你的生产逻辑;也不是你的测试用例。请注意:您也不需要进行奇怪的断言。你希望抛出异常;没有别的。这就是你要检查的内容!
谈论断言;当你需要断言时,了解断言,如
Card underTest = new Card(1, 2);
assertThat(underTest.getSuit(), is(2));
最后:考虑改变套装的类型和排名。让他们真正的类。当然,您可以从int输入构建Rank类;但也许,还有其他选择。事情是:编程是关于创建抽象。如果你不使用抽象......那么你必须处理那些低级细节所有时间。就像你的Card类必须知道有效的int-rank应该是什么样子。如果你有Rank和Suit课程,那么Card只能获得Rank和Suit;并且不必担心int范围!
答案 1 :(得分:0)
如果你遇到异常,除非它再次被抛出catch区块,否则它不会被再次捕获。
使用Junit你可以做这样的事情
e.g。
@Rule public ExpectedException thrown = ExpectedException.none();
@Test
public void throwsException() {
thrown.expect(NullPointerException.class);
thrown.expectMessage("happened");
throw new NullPointerException("What happened?");
}
http://junit.org/junit4/javadoc/4.12/org/junit/rules/ExpectedException.html