I'm just starting out with unit tests (junit). I saw a couple of videos from Roy Osherove, where he talked about good practices. Since I'm pretty new to this subject, I feel totally lost. Below is a short example of my code, which is then followed by how I tested so far and how I would create a fitting junit test. In essence I'm creating a card deck with 52 cards. I want to test if the deck contains all 52 cards, when I create a new "deck" object.
I may have some errors in my code, but it's more about the logic (see the questions in the end).
The production code
Imagine I want to create a common card deck, which consists of 4 suits and 13 ranks. Let's also assume that I created a "card" class and a "deck" class, that contains an instance variable, that's an array consisting of 52 cards.
The "card" class:
public class card {
private String[] suits = {"h", "s", "c", "d"};
private String[] ranks = {"2","3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
private String suit, rank;
public card (int rank, int suit) {
this.suit = this.suits[suit];
this.rank = this.ranks[rank];
}
public String getRank () {
return rank;
}
public String getSuit () {
return suit;
}
}
The "deck" class:
public class deck {
private card[] deckCards = new card[52];
public deck() {
int i = 0;
for(int suit = 0; suit<4; suit++) {
for(int rank=0; rank<13; rank++) {
this.deckCards[i] = new card(rank,suit);
i = i+1;
}
}
}
public card[] getDeckCards() {
return deckCards;
}
}
The Test
So, if I want to create a junit test, my test would look like the follow right?
public class Main {
public static void main(String[] args) {
deck deck = new deck();
int counter = 0;
for (int i = 0; i<52; i++) {
if (deck.deckCards[i] != null) counter++;
}
System.out.println("Cards in deck: " + counter);
for (int i = 0; i<52; i++) {
if (deck.deckCards[i] != null) System.out.println(deck.deckCards[i].getRank() + deck.deckCards[i].getSuit());
}
}
}
As a result I would get something like this:
- Cards in deck: 52
- 2h,3h,4h,5h,6h,7h,8h,9h,Th,Jh,Qh,Kh,Ah, 2s,3s,4s,5s,6s,7s,8s,9s,Ts,Js,Qs,Ks,As, 2c,3c,4c,5c,6c,7c,8c,9c,Tc,Jc,Qc,Kc,Ac, 2d,3d,4d,5d,6d,7d,8d,9d,Td,Jd,Qd,Kd,Ad
Now I can look at all the cards and I would see that everything worked out like i wanted it. Obviously that's not how you test..
Now, if I wanted to create a Junit Test, I would do the following:
@Test
public void testDeck() {
// create the expected value; which is 52 cards
card[] expected = {new card(0,0),
new card(1,0),
new card(2,0),
... ,
new card(12,0),
new card(0,1),
... ,
new card(12,1),
new card(0,2),
... ,
new card(12,2),
new card(0,3),
... ,
new card(12,3)}
// instantiate the deck
deck carddeck = new deck();
card[] actuals = carddeck.getCardDeck();
//assert
assertArrayEquals(expected, actuals);
}
Now, I have a few questions:
- Roy says that we shouldn't use ANY logic in a test method/case. Obviously I do use logic in to create my "expected", namely the constructor of the card class. But how can I use hard coded values? Easy when I do have string or a int as the expected, but what if I do have more complex structures, like this object?
- What if my card deck would have 1000 cards. Then it would be impossible to create an array with 1000 fields manually. But how could I test it otherwise?
Thanks so much for helping me :)
Aucun commentaire:
Enregistrer un commentaire