michaelAdam michaelAdam - 5 months ago 30
Java Question

Why is my mock method not being invoked?

When I run the JUnit test, ShuffleTest, I get the response, "Wanted but not invoked: shuffler.shuffle();"
I have seen this question asked many times on SO, but as far as I can tell, I am doing what those answers say. I am instantiating my interface as a mock, and injecting it into my Deck class. Why is it not getting invoked?

public enum Suit {
SPADE("BLACK"),
CLUB("BLACK"),
HEART("RED"),
DIAMOND("RED");

private final String color;
Suit(String color) {
this.color = color;
}
}

public enum Rank {
ACE, TWO, THREE, FOUR, FIVE, SIX,
SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING;

}


public class Card {
private Suit suit;
private Rank rank;

public Card(Rank rank, Suit suit) {
this.rank = rank;
this.suit = suit;
}

public Suit getSuit() {
return suit;
}

public Rank getRank() {
return rank;
}

public String toString() {
return suit + " of " + rank + ";";
}
}

public class Deck {

private List<Card> cards;
private Shuffler shuffler;

public Deck(Shuffler shuffler) {
this.cards = new LinkedList<Card>();
this.shuffler = shuffler;
shuffler.shuffle(this.cards);
System.out.println("class " + shuffler.getClass());
}

public void shuffle() {
shuffler.shuffle(this.cards);
}
public void addCard(Card card) {
cards.add(0, card);
}

}

public interface Shuffler {
public <T> void shuffle(List<T> items);
}
public class TestDeck {
private Deck deck;
private Shuffler mockShuffler;

public static Deck createFullDeck(Shuffler shuffler) {
shuffler = mock(Shuffler.class);
Deck deck = new Deck(shuffler);
for(Suit s : Suit.values()) {
for(Rank r : Rank.values()) {
deck.addCard(new Card(r, s));
}
}
return deck;
}

@Before
public void before() {
mockShuffler = mock(Shuffler.class);
deck = createFullDeck(mockShuffler);
}



@Test
public void ShuffleTest() {
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
System.out.println("Everyday I'm Shuffling");
return null;
}

}).when(mockShuffler).shuffle(Matchers.anyListOf(Card.class));

deck.shuffle();
verify(mockShuffler, times(1)).shuffle(Matchers.anyListOf(Card.class));
}
}

fgb fgb
Answer

You're creating two separate shuffler objects. Try removing shuffler = mock(Shuffler.class); from the createFullDeck method as shuffler is already a mock when passed in.