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。

如果你嘲笑它,这个 namenull 并且你得到 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 我无法复制那个。