测试一张卡片



试图学习如何在Java中测试,并认为我已经持续很长时间了,因为感觉就像我的反复试验越多,我理解的理解越少。我不知道如何通过填充模拟卡来测试甲板?我想能够测试甲板上的第一张卡片实际上是两颗心,然后甲板被改组或将其比较刚刚为测试制作的整个卡片列表,但是现在它完全静止不动。任何人都有任何有良好方式测试甲板的技巧的人?


card.java

package model;
public class Card {
    public enum Value {
        Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Knight, Queen, King, Ace
    }
    public enum Suite {
        Hearts, Spades, Diamonds, Clubs
    }
    private Value value;
    private Suite suite;
    public Card(Value value, Suite suite) {
        if(value == null || suite == null){
            throw new IllegalArgumentException("Argument can't be null");
        }
        this.value = value;
        this.suite = suite;
    }
    public Object getValue() {
        return this.value;
    }
    public Object getSuite() {
        return this.suite;
    }
    public String toString(){
        return value + " of " + suite;
    }
}


deck.java

package model;
import java.util.ArrayList;
public class Deck {
    private ArrayList<Card> cards = new ArrayList<Card>();  
    private CardFactory CF = new CardFactory();
    public Deck(){
        init();
    }
    public void init() {        
        for (int i=0; i<13; i++){    
            for (int j=0; j<4; j++){
                //card = cardFactory.createCard(Card.Value.values()[i], Card.Suite.values()[j]);
                this.cards.add(CF.createCard(Card.Value.values()[i], Card.Suite.values()[j]));          
            }
        }
    }
    public Card getCard() {     
        return cards.remove(0);
    }
    public int cardsLeft() {        
        return cards.size();        
    }   
    public Card getLastCard() {
        return cards.remove(cards.size()-1);
    }
}


cardFactory.java

package model;
public class CardFactory {
    public Card createCard(Card.Value value, Card.Suite suite){
        return new Card(value, suite);
    }
}


decktest.java

package model;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
public class DeckTest {
    @Mock private ArrayList<Card> cards;
    @Mock private Card card;
    @Mock private CardFactory CF;
    @InjectMocks private Deck sut;
    @Before
    public void setUp() throws Exception {
        initMocks(this);
    }   
    @Test   
    public void DeckContains52Cards() {                     
        sut.init();     
        verify(cards, Mockito.times(52)).add(Mockito.any());
    }
    @Test   
    public void getCardIsCalled() {     
        sut.getCard();
        verify(cards).remove(0);        
    }
    @Test   
    public void cardsLeftIsCalled() {       
        sut.cardsLeft();        
        verify(cards).size();       
    }
    @Test   
    public void getLastCardIsCalled() {     
        sut.getLastCard();
        verify(cards).size();       
    }   
}

你弄错了。

首先,您将依赖项分开。CardFactory需要自由制作所需的卡:

public interface (or abstract class) CardFactory {
    public List<Card> getCards();
}

public class PokerCardFactory implements CardFactory {
  public List<Card> getCards() {
    ArrayList<Card> result = new ArrayList<>();
    for (int i=0; i<13; i++){    
      for (int j=0; j<4; j++){
        result.add(this.createCard(Card.Value.values()[i], Card.Suite.values()[j]));          
      }
    }
    return result;
  }
  private Card createCard(Value value, Suite suite) {
     ...
  }
}

然后您注入依赖项(例如在构造函数中)并使用它来生成卡片。

您要测试Deck而不是PokerCardFactory,因此您要注入更简单的CardFactory来简化测试。Mockito来了,允许您创建这样的工厂写作方式更少的代码。

@Mock private CardFactory cardFactory
@Test
public void numberOfCards {
  ArrayList<Card> cards = new ArrayList();
  cards.add(new Card(Value.Two, Suite.Hearts));
  cards.add(new Card(Value.Three, Suite.Aces));
  when(cardFactory.getCards()).thenReturn(cards); // Now we have a CardFactory that will produce a deck with just two cards.
  Deck deck = new Deck(cardFactory); // Dependency injection.
  assertEquals("The number of cards does not match", 2, deck.getNumberOfCards()); // You have tested `getNumberOfCards`.
} 

好吧,如果要测试,甲板上的第一张卡是两个的心,您的测试应该看起来像这样:

Deck deck = new Deck();
Card firstCard = deck.getCard();
assertCard(firstCard, Value.Two, Suite.Hearts) // orwhatever

还没有模拟的需要,是吗?;)

但这基本上是错误的,因为首先,第二张卡可以是空间的王牌,其次,您不想测试" getCard',您想 verify 甲板以正确的顺序调用卡片。无论如何,您都使用了验证,因此无需解释。但是我无论如何都不喜欢这个测试,因为我本身没有任何值。只要混车工作起作用,它是52张卡片,没有复制卡,该测试已经过时了,但我猜仍然适合学习目的。

由于我无法评论, @sjuan76的答案:此测试没有测试任何内容。我可以切换卡,可以删除第一个条目,然后将第二个输入添加到其位置,或者甚至可以将两个null添加到新创建的列表中,并且测试仍然通过。重构后它唯一应该测试的是验证,cardFactory.getCard被称为,因为这是唯一的事情,从测试的角度来看,必须做。

相关内容

  • 没有找到相关文章

最新更新