我一直在学习Java只是一点,所以请建议如何异常抛出测试应该看起来像在这种情况下?我要上赌博机课。然后进行两次测试。我真的不知道"整数"后面应该是什么。在第二个方法(shouldthrowwhennumbersoutorange)。你能告诉我确切的语法吗?
public class GamblingMachine {
public int howManyWins(Set<Integer> userNumbers) throws InvalidNumbersException {
validateNumbers(userNumbers);
Set<Integer> computerNumbers = generateComputerNumbers();
int count = 0;
for (Integer number : userNumbers) {
if (computerNumbers.contains(number)) {
count++;
}
}
return count;
}
private void validateNumbers(Set<Integer> numbers) throws InvalidNumbersException {
if (numbers.size() != 6) {
throw new InvalidNumbersException();
}
if (numbers.stream().anyMatch(number -> number < 1 || number > 49)) { //anyMatch-function to check whether any element in list satisfy given condition
throw new InvalidNumbersException();
}
}
private Set<Integer> generateComputerNumbers() {
Set<Integer> numbers = new HashSet<>();
Random generator = new Random();
while(numbers.size() < 6) {
numbers.add(generator.nextInt(49) + 1);
}
return numbers;
}
}
private GamblingMachine machine = new GamblingMachine();
@ParameterizedTest
@NullAndEmptySource
public void shouldThrowWhenNumbersEmpty(Set<Integer> numbers) throws InvalidNumbersException {
Assertions.assertThrows(NumberFormatException.class, () -> {
Integer.parseInt(" ");
});
}
@ParameterizedTest
@CsvFileSource(resources ="/numbersOutOfRange.cvs", numLinesToSkip = 1)
public void shouldThrowWhenNumbersOutOfRange(Set<Integer> numbers) throws InvalidNumbersException {
Assertions.assertThrows(NumberFormatException.class, () -> {
Integer. //how code should look like here?
});
}
测试的目的是测试一些东西。您的shouldThrowWhenNumbersEmpty
测试不会这样做(好吧,它测试Integer.parseInt(" ")
抛出一些东西。当然是这样。你……不需要测试核心库)。
换句话说,你的赌博机测试需要从你的GamblingMachine类调用一些东西。这个想法是为了测试GamblingMachine。不测试Integer.parseInt
这也是一个奇怪的测试:为什么在火焰中shouldThrowWhenNumbersEmpty
是参数化的?我假设这个测试的要点是:"确保赌博机在传递一组空数字时按设计工作,特别是在设计中声明如果您这样做会抛出InvalidNumbersException
的部分"。
可以这样写:
@Test
public void shouldThrowWhenNumbersEmpty() {
Assertions.assertThrows(InvalidNumbersException.class, () -> {
Set<Integer> empty = Set.of();
machine.howManyWins(empty);
});
}
参数化测试是一个相当奇特的概念。您的测试设置似乎陷入了一个陷阱:您似乎设置了重复所有已经在你的赌博机器类中的逻辑,然后将这个逻辑应用到传入的(参数化的)数据,找出你的赌博机器应该做什么,然后再次检查它的工作。
你不应该这样写测试。测试侧重于特定的结果。参数化测试是有意义的,但前提是您必须为任何给定输入执行的操作大致相同。例如:
参数化测试的良好使用
您有一个csv文件,其中包含一堆行,每一行有6次滚动+正确答案。您的参数化测试以相同的方式对待每一行:使用6个滚动作为输入调用howManyWins
,然后检查howManyWins
是否返回期望的值。
参数化测试使用不当
您有一个csv文件,其中包含一堆行,每一行有6卷。您的参数化测试将计算掷出的正确结果,然后调用赌博机,并检查赌博机给出的答案是否与您计算的相同。
这是不好的:你只是在重复代码。这也意味着您的测试代码本身所做的不仅仅是最基本的工作(它正在做一堆业务逻辑),因此提出了一个问题:那么,谁来测试您的测试?
你的两个测试方法看起来都应该NOT参数化,除非该CSV也包含结果。