Junit测试无法与Math.pow一起正常工作

时间:2019-03-09 08:53:00

标签: java testing junit

由于我只是编程的初学者,所以这可能是一个琐碎的问题。 任务是为以下Junit测试用例编写代码,将数组的元素提升为三次方:

@Test
    public void testCubeArray() {
        FirstSteps firstSteps = new FirstSteps();
        int[] array1 = {1, 2, 3, 0};
        firstSteps.cube(array1);
        int[] arrayResult1 = {1, 8, 27, 0};
        assertArrayEquals(arrayResult1, array1);
        int[] array2 = {100, 200, 3, 10};
        firstSteps.cube(array2);
        int[] arrayResult2 = {1000000, 8000000, 27, 1000};
        assertArrayEquals(arrayResult2, array2);
}

我的代码就是这样public void cube(int[] array) { for (int i = 0; i <= array.length; i++) { int result = (int)Math.pow(i,3); }

测试失败,结果为2,而不是8。我做错了什么?

2 个答案:

答案 0 :(得分:1)

这里的问题很简单(不要怕答案太长,很有趣!)

firstSteps.cube(array1);

您要将数组实例传递给cube方法,这很好。但是

public void cube(int[] array) {
    for (int i = 0; i <= array.length; i++) {
        int result = (int)Math.pow(i,3);
    }
}

您没有触摸输入数组,甚至没有使用它。见

(int)Math.pow(i,3);

您要将计数器变量i而不是pow传递给array[i]方法。 另外,您正在将pow结果分配给有限范围的局部变量,这意味着result变量将以新的初始值连续重新创建,但没有实际用处。

另一个问题在这里

i <= array.length

这将导致ArrayIndexOutOfBoundsException,因为您将查找比array中可用索引更大的索引。请记住,索引从0开始!

例如,您可以将Math.pow结果分配给原始数组

for (int i = 0; i < array.length; i++) {
    array[i] = (int) Math.pow(array[i], 3);
}

由于您知道,数组是由refence传递的,因此其中的每个引用对象都会被更新。

现在,这个

int[] array1 = {1, 2, 3, 0};
firstSteps.cube(array1);
int[] arrayResult1 = {1, 8, 27, 0};
assertArrayEquals(arrayResult1, array1);

将起作用:)


OlivierGrégoire在评论中建议在修改输入数组之间添加一个中间步骤(这是您现在正在做的,通常不是一个好选择,因为它可能导致意外的结果副作用)并使用Stream库。查看评论,并记住其逻辑与下面的Stream解决方案相同,只是在功能上不同。

public int[] cube(final int[] array) {
    // Initialize a new array, with the same size as the input one,
    // to hold the computed value. We will return this array instead
    // of modifying the inputted one. 
    final int[] powResult = new int[array.length];

    for (int i = 0; i < array.length; i++) {
        powResult[i] = (int) Math.pow(array[i], 3);
    }

    return powResult;
}

您现在可以将其用作

// We use array1 only as input
final int[] array1 = {1, 2, 3, 0};
final int[] powResult = firstSteps.cube(array1);
int[] arrayResult1 = {1, 8, 27, 0};

// We use the returned powResult for comparison,
// as array1 has not been touched.
assertArrayEquals(arrayResult1, powResult);

此外,我想向您介绍使用功能方法的版本。

public int[] cube(final int[] array) {
    return IntStream.of(array)
                    .map(v -> (int) Math.pow(v, 3))
                    .toArray();
}

在这里,我们不触摸array输入数组,但是我们使用Stream创建了一个新的修改后的副本。那就是数组变成了int流,我们可以检查该流的每个元素。

.map(v -> (int) Math.pow(v, 3))

如果继续进行编程,您可能会得出结论,该解决方案要好得多。

答案 1 :(得分:0)

这里有很多错误。首先,您既无法在cube方法中创建任何数组,也无法返回和使用该数组,也无法更改现有数组。重写cube方法的主体,如下所示:

public void cube(int[] array) {
    for (int i = 0; i < array.length; i++) {
        array[i] = (int) Math.pow(array[i], 3);
    }
}

现在测试应通过如下:

int[] array2 = {100, 200, 3, 10};
firstSteps.cube(array2);
int[] expected = {1000000, 8000000, 27, 1000};
assertArrayEquals(expected, array2);

应类似地在测试中使用其他断言。