当前位置: 首页 > 知识库问答 >
问题:

如何测试使用Random()但不能两次抽取相同数字的方法

管玉堂
2023-03-14

我正在创建一个java小游戏,它随机地从原始数据列表(使用random().nextint())类型中选择类型,并询问哪种类型更大(或者它们是否相同)。我还这样做了,如果选择了相同的原始数据类型,那么将再次调用random.nextint(),以确保选择是不同的。

我现在的麻烦在于测试代码是否有效。下面是游戏。class:

static final PrimitiveDataType BOOLEAN_TYPE = new PrimitiveDataType("boolean", 0);
    static final PrimitiveDataType BYTE_TYPE = new PrimitiveDataType("byte", 8);
    static final PrimitiveDataType SHORT_TYPE = new PrimitiveDataType("short", 16);
    static final PrimitiveDataType CHAR_TYPE = new PrimitiveDataType("char", 16);
    static final PrimitiveDataType INT_TYPE = new PrimitiveDataType("int", 32);
    static final PrimitiveDataType LONG_TYPE = new PrimitiveDataType("long", 64);
    static final PrimitiveDataType FLOAT_TYPE = new PrimitiveDataType("float", 32);
    static final PrimitiveDataType DOUBLE_TYPE = new PrimitiveDataType("double", 64);
static List<PrimitiveDataType> PRIMITIVE_TYPES = Arrays.asList(BOOLEAN_TYPE, BYTE_TYPE, SHORT_TYPE, CHAR_TYPE,
        INT_TYPE, LONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE);

static List<PrimitiveDataType> chosenDataTypes = new ArrayList<PrimitiveDataType>();

private static int numberOfQuestions; 

static Random numberGenerator = new Random();

static void setChosenDataTypeIndexs(Random numberGenerator) {




    int choice1 =  numberGenerator.nextInt(PRIMITIVE_TYPES.size()-1)+0;
    int choice2 =  numberGenerator.nextInt(PRIMITIVE_TYPES.size()-1)+0;

    System.out.println("Random Roll (1) " +choice1);
    System.out.println("Random Roll (2) " +choice2);
    do {

        choice2 = numberGenerator.nextInt(PRIMITIVE_TYPES.size()-1)+0;

    } while (choice1==choice2);

    Game.chosenDataTypes.add(PRIMITIVE_TYPES.get(choice1));
    Game.chosenDataTypes.add(PRIMITIVE_TYPES.get(choice2));

}

static PrimitiveDataType getChosenDataTypeIndexs(int i) {
    return chosenDataTypes.get(i);
}

public static void setNumberOfQuestions(int i) {

    numberOfQuestions = i;

}

我曾经尝试过用Mockito编写一个testclass,但我不确定我的嘲笑是否正确,因为在骰子滚动输出相同的数字的情况下通过了测试。另外,如果我将Random.NextInt()的输出模拟为特定的,这会不会在查找不同的数字时创建一个无限循环?

public class GameTest {





@Test
public void getChosenDataTypesTest(){


    Random randomNumberMock = Mockito .mock(Random.class);
    when(randomNumberMock.nextInt()).thenReturn(1);

    Game.setChosenDataTypeIndexs(randomNumberMock);

    assertNotEquals(Game.chosenDataTypes.get(0), Game.chosenDataTypes.get(1));

    verify(randomNumberMock,times(2)).nextInt();




}
@Test
public void setNumberOfQuestionsTest(){




    Game.setNumberOfQuestions(1);

    assertEquals(1,Game.getNumberOfQuestions());


}
package org.FaneFonseka.LearningGames2;

import org.junit.Before;
import org.junit.Test;

import java.util.Stack;


/**
 * Created by Fane on 23/12/2016.
 */
public class PicksTest {


private Picks picks;
private Picker fixedPrimitivePicker;
private Stack<PrimitiveDataType> primitiveDataTypeStack;
private PrimitiveDataType primitive1;
private PrimitiveDataType primitive2;
private PrimitiveDataType primitive3;

@Before
public void setup() {


    primitiveDataTypeStack = new Stack<PrimitiveDataType>();
    primitiveDataTypeStack.push(primitive3 = new PrimitiveDataType("int", 32));
    primitiveDataTypeStack.push(primitive2 = new PrimitiveDataType("boolean", 1));
    primitiveDataTypeStack.push(primitive1 = new PrimitiveDataType("boolean", 1));

    fixedPrimitivePicker = new Picker() {

        public PrimitiveDataType pick() {

            return primitiveDataTypeStack.pop();

        }
    };
    picks = new Picks(fixedPrimitivePicker);

}

@Test
public void setFirstPickTest() {

    picks.setPicks();

    assert picks.getFirstPick().equals(primitive1);


}

@Test
public void setSecondPickTest() {

    picks.setPicks();
    assert picks.getSecondPick().equals(primitive3);
}

@Test
public void secondPickIsDifferentFromFirstPickTest() {

    picks.setPicks();
    assert !picks.getFirstPick().equals(picks.getSecondPick());

}



}
package org.FaneFonseka.LearningGames2;

class Picks {
private PrimitiveDataType firstPick;
private PrimitiveDataType secondPick;
private Picker randomPrimitivePicker;

Picks(Picker randomPrimitivePicker) {
    this.randomPrimitivePicker = randomPrimitivePicker;
}

boolean firstPickGreaterThanSecondPick() {

    System.out.println(getFirstPick().getMemorySizeInBits() > getSecondPick().getMemorySizeInBits());
    return getFirstPick().getMemorySizeInBits() > getSecondPick().getMemorySizeInBits();
}

boolean secondPickGreaterThanFirstPick() {

    System.out.println(getFirstPick().getMemorySizeInBits() < getSecondPick().getMemorySizeInBits());
    return getFirstPick().getMemorySizeInBits() < getSecondPick().getMemorySizeInBits();
}

boolean firstPickIsSameSizeAsSecondPick() {
    System.out.println(getFirstPick().getMemorySizeInBits() == getSecondPick().getMemorySizeInBits());
    return getFirstPick().getMemorySizeInBits() == getSecondPick().getMemorySizeInBits();
}

void setPicks() {
    setFirstPick(randomPrimitivePicker);
    setSecondPick(randomPrimitivePicker);

}

private void setFirstPick(Picker randomPrimitivePicker) {

    this.firstPick = randomPrimitivePicker.pick();
}

PrimitiveDataType getFirstPick() {

    return this.firstPick;
}

private void setSecondPick(Picker randomPrimitivePicker) {

    PrimitiveDataType pick;

    do {
        pick = randomPrimitivePicker.pick();
    } while (pick.equals(firstPick));

    this.secondPick = pick;

}

PrimitiveDataType getSecondPick() {

    return secondPick;
}


}

如果您想查看项目的其余部分,可以在这里找到:

https://github.com/fane247/learninggames2

共有1个答案

伊羽
2023-03-14

您可以使用链式的stubbing为您的测试添加多样性,这样您就不会使用随机返回总是相同的数字进行测试。

 when(randomNumberMock.nextInt())
   .thenReturn(4)
   .thenReturn(12);

您还可以参数化您的测试。下面是TestNG的示例。

@DataProvider()
public static Object[][] randomNumbers() {
    return new Object[][] {{2, 3}, {6, 7}, {19, 15}};
}

@Test(dataProvider = "random")
public void getChosenDataTypesTest(int first, int second) {
 when(randomNumberMock.nextInt())
   .thenReturn(first)
   .thenReturn(second);
} 

JUnit对于参数化测试也有类似的特性。

when(randomNumberMock.nextInt(anyInt())
   .thenReturn(4)
   .thenReturn(12);
 类似资料:
  • 我有两个不同的方法,在两个不同的类中。我希望他们都能阅读同一行输入,并检查不同的内容。一个查找“给我冲杯咖啡”之类的说明,另一个查找不同的关键字,如“请”和“谢谢”(这些影响程序对我的反应): 然后我在我的主字符串中调用它们,只是为了测试它们: 我的控制台显示如下: 我知道发生了什么,但我想不出其他办法。我也尝试过使用同一个扫描仪,不同的字符串,但仍然不起作用。我怎样才能使这两种方法都能读取我的第

  • 我有一个 TestNG 测试套件运行良好,除了一件事:我不能两次运行相同的测试。我想运行两次测试的原因是,我正在测试将用户登录/注销的 Web 服务,并且我想验证登录是否有效,然后注销是否有效,然后再次登录它们,以便后续测试(需要用户登录)可以继续。 下面是我的testng.xml的相关部分: 如您所见,“appUserLogintest”被调用了两次。但是,当我调试它时,我可以清楚地看到它只在第

  • 我的两个方法中的操作是相同的,但是输入参数类型不同,那么我该如何优化这两个方法,似乎没有那么重复?因为它们的操作是相同的,但参数类型不同,我该怎么做才能使这段代码更优雅呢?

  • 问题内容: 我有以下接口,我想在类中多次实现: 现在,我希望能够通过以下方式实现此接口: 但是,这给了我错误:在行上: 是否可以使用不同的泛型两次实现接口?如果不是,那么我在这里可以做的下一步工作是什么? 问题答案: 您需要使用内部或匿名类。例如:

  • 因此,上述结构在ClassA中也同样存在。 假设我想编码2个其他类ClassC(使用ClassA的实例)和ClassD(使用ClassB的实例)。除了ClassA和ClassB的实例之外,ClassC和ClassD的代码完全相同。 从示例中可以看出,ClassC和ClassD具有相同的功能,但对tmp使用了不同的类

  • 为了单元测试DTO,我想使用AssertJ的递归比较来比较两个对象(DTO和一个实体)- 我尝试过以下配置,但运气不佳: 比较阶级: DTO: 实体: 在这种情况下,如何配置assertJ?