Think about what aspects you want to test.
Do you want to test...
- ...if 52 cards have made their way into your list?
- ...if you have four different suits in your list?
- ...if you have thirteen numerical and face cards in your list?
Ideally, you should be testing all three aspects, but the real problem comes with the way that your method is written. You can't test one of these things in isolation.
Note that the fact that this function is void
actually matters little. A void
method simply implies that the state of your object has changed, and to test it, you need to test the state. But, I'll get to that in a moment.
First, we need to do some reorganization of your logic.
Let's first write a method that allows us to generate all thirteen cards for a given suit. That should be straightforward enough.
Pay close attention to the visibility of this method. This is a method that we want to expose for testing, but not a method that is inherently open for the world to use. Hence, we use package-private visibility. If you have Guava, consider using @VisibleForTesting
as a friendly reminder to why it's not public
or 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;
}
This can be tested in isolation. Given a valid Suit
, it should be able to:
- generate 13 cards
- contain all thirteen ranks
- have a contiguous suit
Interestingly enough, we've tested 2 out of the 3 things that we care about in this particular function. Now, let's put it back into the void
method.
public void createDeck() {
for (Suit suit : Suit.values()) {
this.cards.addAll(generateCardsForSuit(suit));
}
}
We will have to expose a getter to retrieve the cards
list, so we can actually verify things against an instance of it. Again, note the visibility of the method.
List<Card> getCards() {
return cards;
}
Since we've comfortably tested the number of cards in a given suit, tested their uniformness, and tested that their ranks are correct, all we'd need to do is test that we generate the right number as a result of this method, using getCards()
as a way to peer into the state of the object.
This also opens us up to include jokers, which would introduce 54 cards into the deck as opposed to just 52, which would be a function independent of creating all ranks and suits for the deck.