【问题标题】:Initialising an array of objects in setUp() in JUnit在 JUnit 的 setUp() 中初始化对象数组
【发布时间】:2018-04-25 15:03:57
【问题描述】:

我正在尝试使用 setUp 为我的测试方法在 JUnit 中初始化一个对象数组,但是我做错了,因为测试引发了错误(空指针异常)。当我在测试方法本身中初始化数组时,它们运行良好,但这显然并不理想。谁能指出我在这里做错了什么?

class MainTest {

    Lord baratheons[];
    Lord starks[];

    //Setup & Teardown

    @Before
    static void setUp() throws Exception {
        Lord baratheons[] = new Lord[3];
        baratheons[0] = new Lord("Robert", 15);
        baratheons[1] = new Lord("Renly", -5);
        baratheons[2] = new Lord("Stannis", 30);
        System.out.println("Baratheons initialised!");

        Lord starks[] = new Lord[3];
        starks[0] = new Lord("Robb", -60);
        starks[1] = new Lord("Eddard", 0);
        starks[2] = new Lord("Jon", 90);
        System.out.println("Starks initialised!");
    }

    //Tests

    @Test
    void testGratefulLord() {
//      Lord baratheons[] = new Lord[3];
//      baratheons[0] = new Lord("Robert", 15);

        int x = baratheons[0].getRelationship();
        baratheons[0].giveFief();
        assertEquals(baratheons[0].getRelationship(), (x+=10));

    }

编辑:

注意 除了遵循以下解决方案中概述的步骤外,我还想为后人指出,我也使用了错误的标签进行设置。因为这是 JUnit 5,所以标签是 @BeforeEach。 @Before 是 JUnit 4 的标签,这就是没有调用 setup 方法的原因。我希望这对未来的用户有所帮助。

【问题讨论】:

  • 这是一个范围问题。您在 setUp() 中声明了一个与全局数组同名的数组。只需执行baratheons = new Lord[3]; 就可以了
  • 此外,为了获得良好的编码风格,您应该将数组括号放在类之后,而不是变量名。所以请改用Lord[] baratheons
  • 就像在setUp()?这可以防止int x = baratheons[0].getRelationship(); 无法将baratheon 解析为变量。
  • 除非您删除了全局声明,否则它应该不会无法解析。保留它,只需在 setUp() 中将行更改为 baratheons = new Lord[3];starks = new Lord[3];
  • 然后从setUp方法中删除static

标签: java arrays object junit


【解决方案1】:

这里的问题是您在 setUp() 方法中重新声明了数组。这会弄乱您要使用的对象的范围。

setUp() 方法中删除static,因为这不需要。

更改您的代码

Lord baratheons[] = new Lord[3];
Lord starks[] = new Lord[3];

baratheons = new Lord[3];
starks = new Lord[3];

最后,您需要将方法更改为public。为什么?因为 JUnit 在幕后使用反射,它们需要公开才能识别。您可以查看 JUnit JavaDoc 并看到它明确提到了 public void 方法

【讨论】:

  • 我按照您的步骤操作,但仍然收到空指针异常。我在setUp() 之外声明了Lord[] baratheons;,在setUp() 内部声明了baratheons = new Lord[3];。同上starks
  • 我在您的代码和我运行的代码之间看到的唯一其他区别是我在所有方法前面都有public,并将全局变量声明为private - 但我不明白为什么那会影响任何事情。让我更深入地研究一下。你能发布堆栈跟踪的重要部分吗?
  • 顺便说一句,您使用的是什么版本的 JUnit?
  • 我错了,方法public - 添加到我的答案中
【解决方案2】:

setUp 方法中删除static

还有

Lord baratheons[] = new Lord[3];

应该是

baratheons = new Lord[3];

starks 也是如此。

【讨论】:

  • baratheons[] 在“应该”是不正确的。那里不应该有括号
【解决方案3】:

setUp() 不应该是静态的。

您在 setUp() 方法中实例化的数组被分配给局部变量。

Lord baratheons[] = new Lord[3];

您在此处声明的变量隐藏了您的类属性。您应该只删除此处的类 (Lord) 以将您的新数组分配给好变量。

baratheons = new Lord[3];

还要小心你的断言语句:

assertEquals(baratheons[0].getRelationship(), (x+=10));

此语句有效,但在此处使用 '+=' 语法可能会导致错误。在这种情况下,代码非常简单,但是如果您想更改 x 的值,提取语句“x+=10”,您将获得更清晰的信息。如果你不需要改变这个值,你可以使用 x+10 来代替。

【讨论】:

    【解决方案4】:

    这里的问题是变量baratheonsstarks 的范围。

    阅读Scope of a Declaration 上的 Java 规范,以更好地理解问题。

    希望这可以帮助您进一步了解这个问题。

    你的代码应该如下:

    class MainTest {
    
        private Lord[] baratheons;
        private Lord[] starks;
    
        //Setup & Teardown
    
        @Before
        public void setUp() throws Exception {
            baratheons= new Lord[3];
            baratheons[0] = new Lord("Robert", 15);
            baratheons[1] = new Lord("Renly", -5);
            baratheons[2] = new Lord("Stannis", 30);
            System.out.println("Baratheons initialised!");
    
            starks = new Lord[3];
            starks[0] = new Lord("Robb", -60);
            starks[1] = new Lord("Eddard", 0);
            starks[2] = new Lord("Jon", 90);
            System.out.println("Starks initialised!");
        }
    
        @Test
        public void testGratefulLord() {
            int x = baratheons[0].getRelationship();
            baratheons[0].giveFief();
            assertEquals(baratheons[0].getRelationship(), (x += 10));
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-22
      • 1970-01-01
      • 2017-02-16
      • 1970-01-01
      • 2020-12-10
      • 2017-02-18
      相关资源
      最近更新 更多