0

我对 Url 连接的测试工作正常。然后 1 个月后,我在应用程序中运行了所有测试并测试 URL 连接失败,我不知道为什么,因为我没有更改这个类。请问,有人可以看看这个测试吗?

测试现在抛出一个java.lang.NullPointerException

测试的最初想法来自:https ://programmingproblemsandsolutions.blogspot.com/2019/04/abstractmethoderror-is-throw-on.html

测试:

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import static org.junit.jupiter.api.Assertions.assertTrue;

@RunWith(PowerMockRunner.class)
@PrepareForTest({URL.class})
class JsonOutputFromURLImplTest
{
    @Test
    void currencyValuesNBP() throws IOException
    {
        class UrlWrapper
        {
            private URL url;

            public UrlWrapper(String spec) throws MalformedURLException
            {
                url = new URL(spec);
            }

            private URLConnection openConnection() throws IOException
            {
                return url.openConnection();
            }
        }

        UrlWrapper url = PowerMockito.mock(UrlWrapper.class);
        HttpURLConnection httpURLConnection = Mockito.mock(HttpURLConnection.class);
        PowerMockito.when(url.openConnection()).thenReturn(httpURLConnection);
        assertTrue(url.openConnection() instanceof HttpURLConnection);
    }
}

测试类:

@Service
@NoArgsConstructor
public class JsonOutputFromURLImpl implements JsonOutputFromURL
{

    @Override
    public String currencyValuesNBP(String APIUrl) throws ConnectionWithApiEX
    {
        String jsonOutput = null;

        try {
            URL url = new URL(APIUrl);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");

            InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            jsonOutput = bufferedReader.readLine();

            httpURLConnection.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(jsonOutput != null)
            return jsonOutput;

        throw new ConnectionWithApiEX(APIUrl);
    }
}
java.lang.NullPointerException
    at com.bartosz.kolej.stock.service.impl.JsonOutputFromURLImplTest$1UrlWrapper.openConnection(JsonOutputFromURLImplTest.java:36)
    at com.bartosz.kolej.stock.service.impl.JsonOutputFromURLImplTest$1UrlWrapper.access$000(JsonOutputFromURLImplTest.java:25)
    at com.bartosz.kolej.stock.service.impl.JsonOutputFromURLImplTest.currencyValuesNBP(JsonOutputFromURLImplTest.java:42)
    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.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
    at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:108)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
4

1 回答 1

1

简短的回答:将您的标记UrlWrapper.openConnection为公开,您就可以开始了。

其次:你没有在你的服务类中测试任何方法,它的代码是无关紧要的。

第三:PowerMock 可以模拟私有方法,它对你不起作用的原因很复杂。

  • 您使用 Junit 5 注释。使用 JUnit4 和 JUnit5 注释时,相同测试的行为不同

考虑下面的类

public static class MyClass {
    public String A() {
        System.out.println("A called");
        return "A";
    }

    private String B() {
        System.out.println("B called");
        return "B";
    }

}

使用 Junit4 注释:

@org.junit.Test
public void testMockPrivateMethod() throws Exception {
    MyClass myClass = PowerMockito.mock(MyClass.class);
    PowerMockito.when(myClass.B()).thenReturn("mockB");
    //PowerMockito.when(myClass, "B").thenReturn("mockB");
    System.out.println(myClass.B());
}

Output:
mockB

使用 Junit5 注释:

@org.junit.jupiter.api.Test
public void testMockPrivateMethod() throws Exception {
    MyClass myClass = PowerMockito.mock(MyClass.class);
    PowerMockito.when(myClass.B()).thenReturn("mockB");
    System.out.println(myClass.B());
}

Output:
B called

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

这是因为您需要字节码检测来模拟私有方法。不幸的是,Junit5 引擎不使用 PowerMockRunner(它有自己的扩展机制)。请注意,您可以将 Junit4 注释与 Junit5 一起使用,但您需要导入vintage runner。

如您所见,正在调用真正的方法。不幸的是,当您的方法抛出 NPE 时,您没有看到异常。

于 2019-06-05T07:06:45.260 回答