Неудачный модульный тест (JUnit + Mockito) - исключение нулевого указателя - PullRequest
0 голосов
/ 05 ноября 2018

Я новичок, поэтому я надеюсь предоставить вам всю необходимую информацию, чтобы помочь мне. Я пытаюсь написать модульный тест (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());
        }
    }
}

Так чего мне не хватает?

1 Ответ

0 голосов
/ 06 ноября 2018

Полагаю, ошибка выдается при выполнении следующей строки:

    defaultSavedRequest = new DefaultSavedRequest(request, portResolver);

Вы издеваетесь над var defaultSavedRequest, но затем пытаетесь инициализировать его реальными методами, но это невозможно для Mock-Object. Mock-Object похож на пустой объект, но с теми же именами методов, что и класс, из которого вы его создаете. Чтобы использовать оригинальные методы из класса, вы должны использовать «шпион» вместо «mock», как, например:

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

Затем вы можете устанавливать и заменять методы в Spy-Object, но все методы, которые не были переопределены вашим тестом, сохраняют свое первоначальное содержание.

...