我在测试void函数时遇到问题。
如果你看下面的代码,那么当我想测试它时,我最终得到了一个(Deck,void),而这个无法测试(请参阅DeckTest)
编辑:如何测试是否创建了一副牌,即public void createDeck()
public class Deck {
public Deck() {
this.cards = new ArrayList<Card>();
}
...
public void createDeck() {
for (Suit suit : Suit.values()) {
for (Rank rank : Rank.values()) {
this.cards.add(new Card(rank, suit));
}
}
}
...
}
现在进行junit测试
public class DeckTest extends TestCase {
Deck deck = new Deck();
@Test
public void testCreateDeck() throws Exception {
assertEquals(deck, deck.createDeck()); <--- I have (Deck, void)
}
...
}
如何使用Junit中的"public void createDeck"来测试是否创建了一个甲板?
全代码的Se链接
https://gist.github.com/kazyka/7a56617337d21706ec5e
考虑一下要测试的方面。
是否要测试。。。
- 。。。如果有52张卡进入了你的名单
- 。。。如果你的清单上有四套不同的西装
- 。。。如果你的名单上有十三张数字和人脸卡
理想情况下,您应该测试所有三个方面,但真正的问题在于您的方法的编写方式。你不能孤立地测试这些东西。
请注意,这个函数是void
这一事实实际上很重要。void
方法简单地表示对象的状态已经更改,要测试它,需要测试状态。但是,我稍后会讲到这一点。
首先,我们需要对你的逻辑进行一些重组。
让我们首先编写一个方法,允许我们为给定的套装生成所有十三张牌。这应该很简单。
请密切关注此方法的可见性这是一种我们想要公开测试的方法,但不是一种本质上开放供世界使用的方法。因此,我们使用包私有可见性。如果你有Guava,可以考虑使用@VisibleForTesting
来友好地提醒你为什么它不是public
或private
。
List<Card> generateCardsForSuit(final Suit suit) {
final List<Card> result = new ArrayList<>();
for(Rank rank : Rank.values()) {
result.add(new Card(rank, suit);
}
return result;
}
这可以单独测试。给定一个有效的Suit
,它应该能够:
- 生成13张卡片
- 包含所有十三个等级
- 穿连身西装
有趣的是,我们已经测试了这个特定函数中我们关心的3件事中的2件。现在,让我们把它放回void
方法中。
public void createDeck() {
for (Suit suit : Suit.values()) {
this.cards.addAll(generateCardsForSuit(suit));
}
}
我们必须公开一个getter来检索cards
列表,这样我们就可以针对它的一个实例进行实际验证。再次注意该方法的可见性。
List<Card> getCards() {
return cards;
}
由于我们已经轻松地测试了给定套装中的卡的数量,测试了它们的一致性,并测试了它们等级的正确性,所以我们所需要做的就是测试我们是否通过这种方法生成了正确的数字,使用getCards()
作为窥视对象状态的一种方式。
这也让我们可以加入小丑,他们会在牌组中引入54张牌,而不是只有52张,这是一个独立于为牌组创建所有等级和套装的功能。
为了便于测试,您可能会考虑按照以下方式重新设计:
Deck
类,以及DeckFactory
如果您这样做,您将能够测试DeckFactory
确实能够构造有效的Deck
实例。通过测试该类,您可以在任何需要新Deck
的地方使用它。
这里有一些粗略的样板,可以告诉你我要说的要点:
public class Cards {
public static void main(String[] args) {
final Deck deck = new DeckFactory().newInstance();
//... do stuff with the deck...
}
}
class Deck {}
class DeckFactory {
public Deck newInstance() {
return new Deck();
}
}
class DeckFactoryTest {
private DeckFactory deckFactory;
@Before
public void setUp() {
deckFactory = new DeckFactory();
}
@Test
public void has52Cards() {
//...
}
@Test
public void has13Spades() {
//...
}
}
assertEquals(deck,deck.createDeck())行将deck对象与void(由createDeck)方法返回)进行比较,因此断言失败。