Java 运行 JUnit 测试时出现 NullPointerException,表示接口为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18771388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 10:54:49  来源:igfitidea点击:

NullPointerException when running JUnit tests, saying interface is null

javainterfacejunitnullpointerexception

提问by Ashton

I'm trying to write a java program that allows the user to input a series of data values then for the program to sort through finding the mean and the median of that series, using an interface to "treat" different objects as if they were the same. However when I run my JUnit test, it keeps saying my interface is null.

我正在尝试编写一个 java 程序,它允许用户输入一系列数据值,然后程序通过查找该系列的平均值和中位数进行排序,使用界面来“处理”不同的对象,就好像它们是相同。但是,当我运行 JUnit 测试时,它一直说我的接口为空。

NoiseFilter.java

噪声过滤器.java

package noisefilter.model;

import java.util.ArrayList;

public interface NoiseFilter {

public double getBestMesurement(ArrayList<Double> samples);

}

AveragingFilter.java

平均过滤器.java

package noisefilter.model;

import java.util.ArrayList;

public class AveragingFilter implements NoiseFilter {

@Override
/**
 * The method getBestMeasurement takes an array list of type double and returns a
 */
public double getBestMesurement(ArrayList<Double> samples) {
    // TODO Auto-generated method stub

    if (samples.equals(null)) {
        throw new IllegalArgumentException("The Samples cannot be null");
    }
    if (samples.size() < 3) {
        throw new IllegalArgumentException("The Sample size must have 3");
    }
    double sum = 0.0;
    for (Double number : samples) {
        sum += number;
    }

    return (sum / samples.size());
}

}

SensorData.java

传感器数据.java

package noisefilter.model;

import java.util.ArrayList;

public class SensorData implements NoiseFilter {

ArrayList<Double> data;
NoiseFilter filter;

public SensorData() {
    this.data = new ArrayList<Double>();
    this.filter = null;
}

public void addSample(double sample) {
    data.add(sample);
}

public void setFilter(NoiseFilter filterVar) {
    this.filter = filterVar;
}

public double getFilteredResult() {
    if (filter.equals(null)) {
        throw new IllegalStateException("The filter cannot be left null");
    }
    return filter.getBestMesurement(data);
}

@Override
public double getBestMesurement(ArrayList<Double> samples) {

    samples = this.data;
    return 0;
}

WhenAveragingFilter.java (JUnit Test)

WhenAveragingFilter.java(JUnit 测试)

package noisefilter.tests;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import noisefilter.model.NoiseFilter;
import noisefilter.model.SensorData;

public class WhenAverageFiltering {

NoiseFilter filter;
SensorData dataSet;


@Before
public void setUp() throws Exception {
    this.dataSet = new SensorData();
    dataSet.setFilter(filter);
}

@Test
public void averageOfThree100sShouldBe100() {
    dataSet.addSample(100);
    dataSet.addSample(100);
    dataSet.addSample(100);

    assertTrue(dataSet.getFilteredResult() == 100);
}

@Test
public void averageOfThreeDifferent() {
    dataSet.addSample(120);
    dataSet.addSample(140);
    dataSet.addSample(130);

    assertTrue(dataSet.getFilteredResult() == 130);
}

@Test
public void averageOfFiveDifferent() {
    dataSet.addSample(10);
    dataSet.addSample(50);
    dataSet.addSample(60);

    assertTrue(dataSet.getFilteredResult() == 40);
}

}

Here's the errors that I get when I run the JUnit Test.

这是我运行 JUnit 测试时遇到的错误。

java.lang.NullPointerException
at noisefilter.model.SensorData.getFilteredResult(SensorData.java:24)
at     noisefilter.tests.WhenAverageFiltering.averageOfFiveDifferent(WhenAverageFiltering.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access
NoiseFilter filter;
SensorData dataSet;


@Before
public void setUp() throws Exception {
    this.dataSet = new SensorData();
    dataSet.setFilter(filter);
}
0(ParentRunner.java:53) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

采纳答案by Sotirios Delimanolis

You never initialize the filterfield in the test class

您永远不会初始化filter测试类中的字段

public void setFilter(NoiseFilter filterVar) {
    this.filter = filterVar;
}

so it is nullhere and that reference propagates to the SensorDataobject you are testing.

所以它在null这里并且该引用传播到SensorData您正在测试的对象。

@Before
public void setUp() throws Exception {
    this.filter = new AveragingFilter(); // or something like it
    this.dataSet = new SensorData();
    dataSet.setFilter(filter);
}

filterVaris nullwhen you call the above.

filterVarnull当你打电话给上面。

You have to initialize it with an implementation of your interface, such as your AveragingFilter:

您必须使用接口的实现对其进行初始化,例如AveragingFilter

if( x.equals( null ) ) {...

Also, you are testing for null in a few places using this pattern:

此外,您正在使用此模式在几个地方测试 null:

if( x == null ) { ...

This will not work, because this is calling the equals(Object)method on the object x. In Java, nulldoes not have any methods. You always have to check for null against its identity, using the ==operator. Your examples should read:

这将不起作用,因为这是调用equals(Object)对象上的方法x。在Java中,null没有任何方法。您始终必须使用运算符根据其身份检查 null ==。你的例子应该是:

filter = new NoiseFilter() {
    public double getBestMesurement(ArrayList<Double> samples) {
        return 100; // or do something else
    }
}

dataSet.setFilter(filter);

回答by hagbard

Your setUp()method does not create a filter.

您的 setUp() 方法不会创建过滤器。

It creates an instance of SensorData and then passes a null value to setFilter. When getFilteredResult() is called later on it runs into a NPE.

它创建一个 SensorData 实例,然后将一个空值传递给 setFilter。当稍后调用 getFilteredResult() 时,它会遇到 NPE。

Added after commenting:

评论后补充:

Anonymous class:

匿名类:

import static org.mockito.Mockito.*;
import static org.mockito.Matchers.*

// ...

filter = Mockito.mock( NoiseFilter.class );
when( filter.getBestMesurement( anyListOf( Double.class ) ) ).thenReturn( 100.0 )

dataSet.setFilter(filter);

with Mockito:

与 Mockito:

##代码##