jenkins 版本设置为 2.X 时出现空指针异常
Null pointer exception when jenkins version is set to 2.X
我有一个 jenkins 版本设置为 1.580 的插件。3.And 当我将 jenkins 版本升级到 1.642.3<=version 时,它抛出一个空指针 exception.Below 是堆栈跟踪
java.lang.NullPointerException
at hudson.model.Label.hashCode(Label.java:528)
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at java.util.Collections.addAll(Collections.java:5401)
at com.google.common.collect.Sets.newHashSet(Sets.java:183)
at com.ericsson.oss.axis.ATest.setUp(ATest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
下面是我的代码
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterValue;
import org.mockito.Answers;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.XXXXX.JenkinsUtils;(internal)
import com.google.common.collect.Sets;
import hudson.model.AbstractBuild;
import hudson.model.Label;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import jenkins.model.Jenkins;
@RunWith(PowerMockRunner.class)
@PrepareForTest( JenkinsUtils.class)
public class A{
@Mock
private Label label;
@Mock
private Jenkins jenkins;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
@Before
public void setUp() {
PowerMockito.mockStatic(JenkinsUtils.class);
try {
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(NodeLabelParameterUtils.class )
public class B{
private BaselineDefinedMessageDispatcher unit;
private BuildData buildData = new BuildData();
private MyBuildDetails myBuildDetails;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
@Mock
private BuildLogger buildLogger;
@Mock
private Label label;
@Mock
private Computer computer;
@Mock
private PretendSlave node;
@Mock
private FreeStyleProject project;
@Mock
private Jenkins jenkins;
@Mock
private EnvironmentVariableResolver envVarsResolver;
@Before
public void setUp() throws IOException, InterruptedException, Descriptor.FormException {
unit = spy(new BaselineDefinedMessageDispatcher(null, null));
unit.setBuildLogger(mock(BuildLogger.class));
MyBuildDetails = mock(MyBuildDetails.class);
doReturn("expectedSlaveHost").when(unit).getHostNameFromSlave(any(Node.class));
doReturn(project).when(build).getProject();
doReturn(Sets.<Node>newHashSet(node)).when(label).getNodes();
doReturn(node).when(build).getBuiltOn();
doReturn(jenkins).when(unit).getJenkinsInstance();
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
PowerMockito.mockStatic(A.class);
when(envVarsResolver.processString(anyString())).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
return (String) invocationOnMock.getArguments()[0];
}
});
}
正在使用以下依赖项
powermock-api-mockito - 1.6.3
mockito-core - 1.9.5
junit - 4.11
java - 1.8
jenkins.version - 1.642.3
我在 doReturn(Sets.newHashSet(label)).when(jenkins).getLabels(); 处得到错误在 class A.
这是一个 Maven 项目,当 jenkins 版本设置为 1.580.3 时,mvn clean install 是成功的,但是当版本>=1.642.3 时,它失败了。
我的目标是将 jenkins verison 升级到 2.X.I 在 Whosebug 中经历了很多解决方法但没有任何效果
感谢任何帮助
编辑:
看来我原来的回答不正确。
NPE 是因为抽象 Label
class 有一个名为 name
的构造函数参数。该参数用于计算标签的hashcode。
如果你嘲笑它,这个 name
是 null
并且你得到 NPE。
现在的问题是您需要为此创建模拟还是可以实际使用真实实例?在下面的示例中,我只使用了 class LabelAtom
的实现之一。如果因为需要在对象上定义一些否则无法获得的行为而需要模拟,则可能必须使用 spy
.
(使用 org.jenkins-ci.main:jenkins-core:2.85
测试)
import static org.mockito.Mockito.doReturn;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.collect.Sets;
import hudson.model.Label;
import hudson.model.labels.LabelAtom;
import jenkins.model.Jenkins;
@RunWith(PowerMockRunner.class)
public class Test {
@Mock
private Jenkins jenkins;
private Label label;
@Before
public void setUp() {
Assert.assertNotNull(jenkins);
label = new LabelAtom("someName");
// or if a mock is required
//label = Mockito.spy(new LabelAtom("someName"));
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
}
@Test
public void test() {
}
}
关于 WithOrWithoutExpectedArguments
我无法复制那个。
我有一个 jenkins 版本设置为 1.580 的插件。3.And 当我将 jenkins 版本升级到 1.642.3<=version 时,它抛出一个空指针 exception.Below 是堆栈跟踪
java.lang.NullPointerException
at hudson.model.Label.hashCode(Label.java:528)
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at java.util.Collections.addAll(Collections.java:5401)
at com.google.common.collect.Sets.newHashSet(Sets.java:183)
at com.ericsson.oss.axis.ATest.setUp(ATest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
下面是我的代码
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterValue;
import org.mockito.Answers;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.XXXXX.JenkinsUtils;(internal)
import com.google.common.collect.Sets;
import hudson.model.AbstractBuild;
import hudson.model.Label;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import jenkins.model.Jenkins;
@RunWith(PowerMockRunner.class)
@PrepareForTest( JenkinsUtils.class)
public class A{
@Mock
private Label label;
@Mock
private Jenkins jenkins;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
@Before
public void setUp() {
PowerMockito.mockStatic(JenkinsUtils.class);
try {
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(NodeLabelParameterUtils.class )
public class B{
private BaselineDefinedMessageDispatcher unit;
private BuildData buildData = new BuildData();
private MyBuildDetails myBuildDetails;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
@Mock
private BuildLogger buildLogger;
@Mock
private Label label;
@Mock
private Computer computer;
@Mock
private PretendSlave node;
@Mock
private FreeStyleProject project;
@Mock
private Jenkins jenkins;
@Mock
private EnvironmentVariableResolver envVarsResolver;
@Before
public void setUp() throws IOException, InterruptedException, Descriptor.FormException {
unit = spy(new BaselineDefinedMessageDispatcher(null, null));
unit.setBuildLogger(mock(BuildLogger.class));
MyBuildDetails = mock(MyBuildDetails.class);
doReturn("expectedSlaveHost").when(unit).getHostNameFromSlave(any(Node.class));
doReturn(project).when(build).getProject();
doReturn(Sets.<Node>newHashSet(node)).when(label).getNodes();
doReturn(node).when(build).getBuiltOn();
doReturn(jenkins).when(unit).getJenkinsInstance();
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
PowerMockito.mockStatic(A.class);
when(envVarsResolver.processString(anyString())).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
return (String) invocationOnMock.getArguments()[0];
}
});
}
正在使用以下依赖项
powermock-api-mockito - 1.6.3
mockito-core - 1.9.5
junit - 4.11
java - 1.8
jenkins.version - 1.642.3
我在 doReturn(Sets.newHashSet(label)).when(jenkins).getLabels(); 处得到错误在 class A. 这是一个 Maven 项目,当 jenkins 版本设置为 1.580.3 时,mvn clean install 是成功的,但是当版本>=1.642.3 时,它失败了。 我的目标是将 jenkins verison 升级到 2.X.I 在 Whosebug 中经历了很多解决方法但没有任何效果 感谢任何帮助
编辑:
看来我原来的回答不正确。
NPE 是因为抽象 Label
class 有一个名为 name
的构造函数参数。该参数用于计算标签的hashcode。
如果你嘲笑它,这个 name
是 null
并且你得到 NPE。
现在的问题是您需要为此创建模拟还是可以实际使用真实实例?在下面的示例中,我只使用了 class LabelAtom
的实现之一。如果因为需要在对象上定义一些否则无法获得的行为而需要模拟,则可能必须使用 spy
.
(使用 org.jenkins-ci.main:jenkins-core:2.85
测试)
import static org.mockito.Mockito.doReturn;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.collect.Sets;
import hudson.model.Label;
import hudson.model.labels.LabelAtom;
import jenkins.model.Jenkins;
@RunWith(PowerMockRunner.class)
public class Test {
@Mock
private Jenkins jenkins;
private Label label;
@Before
public void setUp() {
Assert.assertNotNull(jenkins);
label = new LabelAtom("someName");
// or if a mock is required
//label = Mockito.spy(new LabelAtom("someName"));
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
}
@Test
public void test() {
}
}
关于 WithOrWithoutExpectedArguments
我无法复制那个。