Java JUNIT空指针异常

Java JUNIT空指针异常,java,testing,junit,Java,Testing,Junit,这是我第一次使用JUNIT,实际上我无法让它工作 我有一个person类,其中有firstName和lastName,还有一个测试类,我需要在其中测试方法。但每次我尝试测试一个方法时,如果我为特定方法编写了测试,它就会失败 这是我的密码 个人类别 public class Person { private String firstName; private String lastName; public Person (String a, String b) {

这是我第一次使用JUNIT,实际上我无法让它工作

我有一个person类,其中有firstName和lastName,还有一个测试类,我需要在其中测试方法。但每次我尝试测试一个方法时,如果我为特定方法编写了测试,它就会失败

这是我的密码

个人类别

public class Person {
    private String firstName;
    private String lastName;    

    public Person (String a, String b) {
        firstName = a;
        lastName = b;
    }

    public String getfirstName() {
        return firstName;
    }

    public void setfirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getlastName() {
        return lastName;
    }

    public void setlastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return  firstName + " " + lastName;
    }
}
public class PersonTest {
    Person p1;

    public PersonTest() {
        Person p1 = new Person ("Thomas", "Brown");
    }

    @Before
    public void setUp() {}

    @After
    public void tearDown() {}

    @Test
    public void testGetfirstName() {
        assertEquals("Thomas", p1.getfirstName());
    }

    @Test
    public void testSetfirstName() {}

    @Test
    public void testGetlastName() {
        assertEquals("Brown", p1.getlastName());
    }

    @Test
    public void testSetlastName() {}

    @Test
    public void testToString() {
        assertEquals("Thomas Brown", p1.toString());
    }
}
个人测试类

public class Person {
    private String firstName;
    private String lastName;    

    public Person (String a, String b) {
        firstName = a;
        lastName = b;
    }

    public String getfirstName() {
        return firstName;
    }

    public void setfirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getlastName() {
        return lastName;
    }

    public void setlastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return  firstName + " " + lastName;
    }
}
public class PersonTest {
    Person p1;

    public PersonTest() {
        Person p1 = new Person ("Thomas", "Brown");
    }

    @Before
    public void setUp() {}

    @After
    public void tearDown() {}

    @Test
    public void testGetfirstName() {
        assertEquals("Thomas", p1.getfirstName());
    }

    @Test
    public void testSetfirstName() {}

    @Test
    public void testGetlastName() {
        assertEquals("Brown", p1.getlastName());
    }

    @Test
    public void testSetlastName() {}

    @Test
    public void testToString() {
        assertEquals("Thomas Brown", p1.toString());
    }
}

有人能给我指出正确的方向吗?

这是正确的方法:

@Before
public void setUp() {
    p1 = new Person ("Thomas", "Brown");
}
您的代码中有两个问题

public PersonTest() {
    Person p1 = new Person ("Thomas", "Brown");
}
这将创建一个局部变量,您的字段
p1
将保持
null

第二,在
设置
方法中,您不初始化
p1

您在之前用
@注释的方法将在每次测试之前运行,您应该将初始化放在那里。我还建议使用更具描述性的名称,因此您应该将
p1
更改为
target
或类似的名称

编辑:对于您的
设置…
方法,您可以执行以下操作:

public class PersonTest {
    private static final String TEST_FIRST_NAME = "some name";

    Person target;

    // ...
    @Test
    public void testSetFirstName() {
        target.setFirstName(TEST_FIRST_NAME);
        Assert.assertEquals(target.getFirstName(), TEST_FIRST_NAME);
    }
}
在这一点上,您可以假设
getFirstName
可以工作,因为您也对它进行了测试


旁注:我认为只要使用Eclipse生成getter和setter,就不必测试它们。这是不必要的。

这是正确的方法:

@Before
public void setUp() {
    p1 = new Person ("Thomas", "Brown");
}
您的代码中有两个问题

public PersonTest() {
    Person p1 = new Person ("Thomas", "Brown");
}
这将创建一个局部变量,您的字段
p1
将保持
null

第二,在
设置
方法中,您不初始化
p1

您在
之前用
@注释的方法将在每次测试之前运行,您应该将初始化放在那里。我还建议使用更具描述性的名称,因此您应该将
p1
更改为
target
或类似的名称

编辑:对于您的
设置…
方法,您可以执行以下操作:

public class PersonTest {
    private static final String TEST_FIRST_NAME = "some name";

    Person target;

    // ...
    @Test
    public void testSetFirstName() {
        target.setFirstName(TEST_FIRST_NAME);
        Assert.assertEquals(target.getFirstName(), TEST_FIRST_NAME);
    }
}
在这一点上,您可以假设
getFirstName
可以工作,因为您也对它进行了测试

旁注:我认为只要使用Eclipse生成getter和setter,就不必测试它们。这是不必要的。

改变

Person p1 = new Person ("Thomas", "Brown"); //this is local variable

改变

Person p1 = new Person ("Thomas", "Brown"); //this is local variable


人员p1…
的创建移动到您的
@Before
方法。将
人员p1…
的创建移动到您的
@Before
方法。非常感谢。我还对如何测试集合方法感到困惑?你能给我指出正确的方向吗?如果你的生产类正在断言输入和/或有效状态,你可能想测试你的访问器/变异器。这是验证器类或类似类的工作,不是吗?是的,但并非所有系统都使用外部验证器类来处理简单的事情,如
null
s和空字符串。这可能是一种过分的做法,但在我正在开发的前一个系统上,我们创建了一个
非null参数化的
方面,它检查业务外观中的所有方法,如果用户提供
null
。在这种情况下,我们只需要测试方面,而不是所有的方法。在一天结束的时候,为了同样的结果,付出的努力要少得多。非常感谢。我还对如何测试集合方法感到困惑?你能给我指出正确的方向吗?如果你的生产类正在断言输入和/或有效状态,你可能想测试你的访问器/变异器。这是验证器类或类似类的工作,不是吗?是的,但并非所有系统都使用外部验证器类来处理简单的事情,如
null
s和空字符串。这可能是一种过分的做法,但在我正在开发的前一个系统上,我们创建了一个
非null参数化的
方面,它检查业务外观中的所有方法,如果用户提供
null
。在这种情况下,我们只需要测试方面,而不是所有的方法。在一天结束时,对于相同的结果,所做的工作要少得多。虽然消除这种别名是正确的,但在测试构造函数(只创建一次)中初始化被测类通常是不好的,而不是在
@Before
方法中(在该方法中,它针对每个
@test
进行初始化)。如果您使用构造函数方法并在任何时候修改测试中的类,您将为所有
@test
方法引入副作用。注意,实际上我对
JUnit
并不熟悉,我只知道NullPointerException的原因:)但是感谢您提供的好信息,希望它对他有用。虽然消除这个别名是正确的,但在测试构造函数(只创建一次)中初始化被测试的类通常是不好的,而不是在
@Before
方法中初始化(在该方法中,它针对每个
@test
进行初始化)。如果您使用构造函数方法并在任何时候修改测试中的类,您将为所有
@test
方法引入副作用。值得注意的是,实际上我对
JUnit
并不熟悉,我只知道NullPointerException:)的原因,但是感谢您提供的好信息,希望它对他有用。