【问题标题】:Failed Unit test (JUnit+Mockito) - Null pointer exception单元测试失败 (JUnit+Mockito) - 空指针异常
【发布时间】:2019-04-09 05:38:07
【问题描述】:

我是新手,所以我希望为您提供帮助我所需的所有信息。 我正在尝试编写一个单元测试(Junit+ Mockito)-检查其他问题但没有成功-在这个特定的方法上

    public void saveRequest(final HttpServletRequest request, final HttpServletResponse response)
{
    //this might be called while in ExceptionTranslationFilter#handleSpringSecurityException in this case base implementation
    if (getSecurityContext().getAuthentication() == null)
    {
        callSuperSaveRequest(request, response);
    }
    else
    {
        final SavedRequest savedBefore = getRequest(request, response);
        if (savedBefore != null)//to not override request saved by ExceptionTranslationFilter#handleSpringSecurityException
        {
            return;
        }

        if (getRequestMatcher().matches(request))
        {
            final DefaultSavedRequest savedRequest = new DefaultSavedRequest(request, getPortResolver())
            {
                private final String referer = request.getHeader(REFERER);

                @Override
                public String getRedirectUrl() { return referer; }
            };

            if (isCreateSessionAllowed() || request.getSession(false) != null)
            {
                request.getSession().setAttribute(SAVED_REQUEST, savedRequest);
                logger.debug("DefaultSavedRequest added to Session: " + savedRequest);
            }
        }
        else
        {
            logger.debug("Request not saved as configured RequestMatcher did not match");
        }
    }
}

这是我写到现在的单元测试

@Test
public void testSaveRequestIfSavedBeforeIsNull()
{
    given(request.getRequestURL()).willReturn(new StringBuffer("dummy"));
    given(request.getScheme()).willReturn("dummy");
    given(request.getHeader("referer")).willReturn("some blah");
    given(portResolver.getServerPort(request)).willReturn(100);
    doReturn(portResolver).when(cache).getPortResolver();
    defaultSavedRequest = new DefaultSavedRequest(request, portResolver);
    doReturn(true).when(cache.isCreateSessionAllowed());
    given(request.getSession()).willReturn(httpSession);

    cache.saveRequest(request, response);

    verify(request.getSession()).setAttribute(Matchers.eq("SPRING_SECURITY_SAVED_REQUEST"),
            Mockito.argThat(new DefaultSavedRequestArgumentMatcher("some blah")));
}

模拟/注入以下实例

    @Spy
@InjectMocks
private WebHttpSessionRequestCache cache;

@Mock
private HttpServletRequest request;

@Mock
private HttpServletResponse response;

@Mock
private SecurityContext securityContext;

@Mock
private PortResolver portResolver;

@Mock
private SavedRequest savedBefore;

@Mock
private Authentication authentication;

@Mock
private DefaultSavedRequest defaultSavedRequest;

@Mock
private HttpSession httpSession;

但这是我的错误

java.lang.NullPointerException
at org.springframework.security.web.savedrequest.DefaultSavedRequest.<init>(DefaultSavedRequest.java:91)
at com.superdrug.storefront.security.impl.WebHttpSessionRequestCacheUnitTest.testSaveRequestIfSavedBeforeIsNull(WebHttpSessionRequestCacheUnitTest.java:116)
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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
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)
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 com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:67)

如果我没记错的话,我认为错误是由另一个类“DefaultSavedRequest”引起的;我试图模拟它,但有些东西不起作用......

这是“DefaultSavedRequest”类

public class DefaultSavedRequest implements SavedRequest {
protected static final Log logger = LogFactory.getLog(DefaultSavedRequest.class);
private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
private final ArrayList<SavedCookie> cookies = new ArrayList();
private final ArrayList<Locale> locales = new ArrayList();
private final Map<String, List<String>> headers;
private final Map<String, String[]> parameters;
private final String contextPath;
private final String method;
private final String pathInfo;
private final String queryString;
private final String requestURI;
private final String requestURL;
private final String scheme;
private final String serverName;
private final String servletPath;
private final int serverPort;

public DefaultSavedRequest(HttpServletRequest request, PortResolver portResolver) {
    this.headers = new TreeMap(String.CASE_INSENSITIVE_ORDER);
    this.parameters = new TreeMap(String.CASE_INSENSITIVE_ORDER);
    Assert.notNull(request, "Request required");
    Assert.notNull(portResolver, "PortResolver required");
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        Cookie[] arr$ = cookies;
        int len$ = cookies.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            Cookie cookie = arr$[i$];
            this.addCookie(cookie);
        }
    }

    Enumeration names = request.getHeaderNames();

    while(true) {
        String name;
        do {
            do {
                if (!names.hasMoreElements()) {
                    Enumeration locales = request.getLocales();

                    while(locales.hasMoreElements()) {
                        Locale locale = (Locale)locales.nextElement();
                        this.addLocale(locale);
                    }

                    Map<String, String[]> parameters = request.getParameterMap();
                    Iterator i$ = parameters.keySet().iterator();

                    while(i$.hasNext()) {
                        String paramName = (String)i$.next();
                        Object paramValues = parameters.get(paramName);
                        if (paramValues instanceof String[]) {
                            this.addParameter(paramName, (String[])((String[])paramValues));
                        } else if (logger.isWarnEnabled()) {
                            logger.warn("ServletRequest.getParameterMap() returned non-String array");
                        }
                    }

                    this.method = request.getMethod();
                    this.pathInfo = request.getPathInfo();
                    this.queryString = request.getQueryString();
                    this.requestURI = request.getRequestURI();
                    this.serverPort = portResolver.getServerPort(request);
                    this.requestURL = request.getRequestURL().toString();
                    this.scheme = request.getScheme();
                    this.serverName = request.getServerName();
                    this.contextPath = request.getContextPath();
                    this.servletPath = request.getServletPath();
                    return;
                }

                name = (String)names.nextElement();
            } while("If-Modified-Since".equalsIgnoreCase(name));
        } while("If-None-Match".equalsIgnoreCase(name));

        Enumeration values = request.getHeaders(name);

        while(values.hasMoreElements()) {
            this.addHeader(name, (String)values.nextElement());
        }
    }
}

那么我错过了什么?

【问题讨论】:

    标签: unit-testing nullpointerexception mockito


    【解决方案1】:

    我想当执行以下行时会抛出错误:

        defaultSavedRequest = new DefaultSavedRequest(request, portResolver);
    

    您模拟 var defaultSavedRequest,然后尝试使用真实方法对其进行初始化,但这对于 Mock-Object 是不可能的。 Mock-Object 就像一个空对象,但具有与您创建它的类相同的方法名称。要使用类中的原始方法,您必须使用“spy”而不是“mock”,例如:

    private DefaultSavedRequest defaultSavedRequest = spy(new DefaultSavedRequest(request, portResolver));
    

    然后您可以设置和替换 Spy-Object 中的方法,但所有未被您的测试覆盖的方法都保留其原始内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 2019-05-24
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      • 2016-08-19
      • 2018-08-27
      相关资源
      最近更新 更多