我有几年前做过的纸牌游戏,现在我已经了解了如何使用Mockito进行嘲笑。到目前为止,我的卡片对象看起来像:
public Card(){
this.value = new CardValue(determineFace()); //assigns the output of a randomly chosen card to Card's this.value
//by plugging a call to determineFace() into a CardValue
this.suit = determineSuit(); //this.suit is assigned a suit at random
}
其中defineFace()是:
public static String determineFace(){ //determines a face at random so that CardValue in this.value's init has a parameter
String f = null;
int rand = (int)(Math.random()*13);
if (rand == 0){
f = "2";
}
if (rand == 1){
f = "3";
}
if (rand == 2){
f = "4";
}
if(rand == 3){
f = "5";
}
if(rand == 4){
f = "6";
}
if(rand == 5){
f = "7";
}
if(rand == 6){
f = "8";
}
if(rand == 7){
f = "9";
}
if(rand == 8){
f = "10";
}
if (rand == 9){
f = "J";
}
if (rand == 10){
f = "Q";
}
if (rand == 11){
f = "K";
}
if(rand == 12){
f = "A";
}
return f;
}
西装是
的一部分public enum Suit{
CLUBS, DIAMONDS, HEARTS, SPADES
}
CardValue为:
protected String face; //a CardValue's verbal name
protected int numeric; //a CardValue's numeric value
public CardValue(String faceVal){
face = faceVal; // set's a CV's face name passed into the constructor
numeric = findNumericVal(faceVal); //sets the numeric value equal to the output of the call to findNumericVal on the faceVal
}
但是,我对如何将CardValue模拟到Mockito感到很困惑,因此可以测试Card的方法。我也想测试CardValue的方法。我不太确定是否要使用@InjectMocks bc,似乎总是将其与没有args参数的对象一起使用。在尝试使用JUnit和Mockito进行模拟并对其进行测试时,我遇到了错误的情况,即在这些paren中使用错误的类型尝试了thenReturn()的情况下,我断言了在null中显示为null的值。如何对对象进行有效的模拟?
答案 0 :(得分:0)
欢迎使用Stackoverflow!
这是一个没有模拟的解决方案,因为我看不到使用模拟的理由。
您需要做的就是在测试中用自定义函数替换随机函数。
AuthorityUrl
类具有一个静态字段Card
,它将在测试中被覆盖。顺便说一句,我将randomGenerator
简化为一行,并删除了显式构造函数,只是为了获得更紧凑的代码。
determineFace()
这是测试类的示例:
class Card {
static Supplier<Integer> randomGenerator = () -> (int) (Math.random() * 13);
static String[] supportedFs =
new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
final CardValue value = new CardValue(determineFace());
final Suite suit = determineSuit();
static String determineFace() {
return supportedFs[randomGenerator.get()];
}
static Suite determineSuit() {
// TODO: to be finished according to your logic.
return Suite.CLUBS;
}
}
当然,您可以使用数据提供程序为每个可能的随机值组合测试用例。
上述解决方案的一个坏处是,将不会测试实际的随机生成。对于这种情况,您可以使用真实随机生成进行测试,但将实际值匹配为受支持值的一部分:
public class CardTest {
@Test
public void cardConstructionWhenRandomIsZero() {
// Given custom random generator which returns always 0.
Card.randomGenerator = () -> 0;
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("2", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}
@Test
public void cardConstructionWhenRandomIsOne() {
// Given custom random generator which returns always 1.
Card.randomGenerator = () -> 1;
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("3", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}
}
更新:基于评论。
如果您仍然想使用@Test
public void cardConstructionWithRealRandom() {
// When
Card actualCard = new Card();
// Then
Assert.assertThat(actualCard.value.face, Matchers.isIn(Card.supportedFs));
}
,可以通过以下方式模拟随机生成器的行为:
Mockito
更新2 :基于评论。
@Test
public void cardConstructionWhenRandomIsZero() {
// Given custom random generator which returns always 0.
Card.randomGenerator = Mockito.mock(Supplier.class);
Mockito.when(Card.randomGenerator.get()).thenReturn(0);
// When
Card actualCard = new Card();
// Then
Assert.assertEquals("2", actualCard.value.face);
Assert.assertEquals(0, actualCard.value.numeric);
Assert.assertEquals(Suite.CLUBS, actualCard.suit);
}