【问题标题】:Mockito mock NullPointerException, don't know what else is there to tryMockito 模拟 NullPointerException,不知道还有什么可以尝试的
【发布时间】:2020-04-29 07:38:09
【问题描述】:

Java 认为我模拟的 Course 类对象在 when().thenReturn() 行为 null。

class StudentTest {

    @Mock
    Course courseMock1;      

    @Test
    void student_getTeacherNames_should_return_list_of_full_names() {    
        when(courseMock1.getEAP()).thenReturn(1);
    }


public class Course {
    public Course(String courseName, String name, LocalDate startDate, LocalDate endDate, Integer EAP, Teacher teacher) {
        this.courseName = courseName;
        this.name = name;
        this.startDate = startDate;
        this.endDate = endDate;
        this.EAP = EAP;
        this.teacher = teacher;
    }
    public Integer getEAP() {
        return EAP;
    }
}

我试过了:

@RunWith(MockitoJUnitRunner.class)
class StudentTest{...

--

@Before
public void setup(){
    MockitoAnnotations.initMocks(this);
}

--

@Rule public Mocks mocks = new Mocks(this);

没有一个能解决 NPE。

也尝试过(使用模拟的 Teacher 对象作为参数之一)

@Mock
Course courseMock1 = new Course(params..);

产生了: MissingMethodInvocationException: when() 需要一个参数,该参数必须是“模拟方法调用”

【问题讨论】:

  • 最简单的版本是Course courseMock = Mockito.mock(Course.class),但请注意不要模拟数据类;只需创建一个 eap 为 1 的实例。
  • 这行得通!那么注释有问题吗?另外,初学者问题,eap 为 1 的实例类型是什么?模拟数据类有什么不好?
  • 注解没有什么错误,只是支持注解的基础设施比mock(Course.class) 更复杂,一般来说最好让事情尽可能简单。不应模拟数据类,因为它们不做任何事情,它们只是具有值,因此new Course("courseName", "name", LocalDate.now(), LocalDate.now(), 1, null) 为您提供所需的 EAP==1,而不会产生不必要的复杂性。

标签: java nullpointerexception mocking mockito


【解决方案1】:

用@RunWith(MockitoJUnitRunner.class)注释StudentTest类。

将StudentTest 类声明为public。

将student_getTeacherNames_should_return_list_of_full_names 方法声明为public。

运行测试类。

@RunWith(MockitoJUnitRunner.class)
public class StudentTest {

    @Mock
    Course courseMock1;      

    @Test
    public void student_getTeacherNames_should_return_list_of_full_names() {    
        Mockito.when(courseMock1.getEAP()).thenReturn(1);
        assertThat(courseMock1.getEAP()).isEqualTo(1);
    }
}

【讨论】:

  • MockitoException: 在 StudentTest 中找不到测试该方法是否用@Test 注释?方法是公开的吗?此外,NPE 仍然存在
  • > 方法是否公开?您是否将student_getTeacherNames_should_return_list_of_full_names 声明为public?
  • 是的,我做到了。我在测试类中还有另一个@Test,一个非公开的。这个现在好像也没有被认出来。理论上,第二个测试“应该”使用模拟,但我不太确定了。
  • 你得到 NPE 是因为你可能没有添加 @RunWith(MockitoJUnitRunner.class) 注释。
  • 第二种方法没有添加有问题。隔离问题。解决这个问题。然后,转到下一个问题。
【解决方案2】:

您使用什么测试框架? junit 4 还是 junit 5?

如果是 junit5 ,那么测试类应该用@ExtendWith(MockitoExtension.class)注解

另一种方法是完全依赖代码(不使用注释)。 代码将变为

class StudentTest {
    Course courseMock1 = Mockito.mock(Course.class);
    ...
}

【讨论】:

    【解决方案3】:

    要使用@Mock 注解,您需要导入 org.mockito.MockitoAnnotations;并调用 MockitoAnnotations.initMocks。请注意,必须在每次测试之前调用该方法。

    @BeforeEach
    void setup() {
        MockitoAnnotations.initMocks(this);
    }
    

    我错误地使用了@Before 而不是@BeforeEach

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多