#unit-testing #wicket
#модульное тестирование #калитка
Вопрос:
Ситуация
Я использую wicket 9 для разработки веб-графического интерфейса. И теперь я пытаюсь провести тестирование junit с помощью насмешливых (mockito) методов, которые не являются существенными. Одним из таких методов является
httpSession.getAttribute("loginName");
который называется так:
public class MyPanel { ... SecureWebSession session = (SecureWebSession) getSession(); lt;--returns a SecuredWebSession Label username = new Label("loginName", session.getLoginName()); lt;-- NullPointerException ... }
Очевидно, что-то не так с тем, как я издеваюсь над вещами. Я ожидаю, что он вернет тест, но все, что я всегда получаю, — это исключение NullPointerException.
Мой вопрос в том, как я могу обойти session.getLoginName (), чтобы вызов вернул тест имени входа?
Как имитировать HttpSession при тестировании приложения wicket?
Подробные сведения
У меня есть класс securedWebSession
package com.my.app.application; import com.my.app.service.signOnService; import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; import org.apache.wicket.authroles.authorization.strategies.role.Roles; import org.apache.wicket.injection.Injector; import org.apache.wicket.request.Request; import org.apache.wicket.spring.injection.annot.SpringBean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.UnsupportedEncodingException; public class SecureWebSession extends AuthenticatedWebSession { @SpringBean(name = "authenticationManager") private AuthenticationManager authenticationManager; @SpringBean(name = "signOnService") private SignOnService signOnService; private final HttpSession httpSession; private final Request request; public SecureWebSession(Request request) { super(request); this.request = request; //******************THIS I CANNOT BYPASS***************************************START this.httpSession = ((HttpServletRequest) request.getContainerRequest()) .getSession(false); //******************THIS I CANNOT BYPASS******ALLWAYS RETURNS NULL*************END Injector.get().inject(this); } @Override public boolean authenticate(String username, String password) { return true; } private boolean hasSignedIn(Authentication authentication) { return authentication.isAuthenticated(); } @Override public Roles getRoles() { Roles roles = new Roles(); roles.add("SUPER_ADMIN"); return roles; } public String getLoginName() { ********RETURNS NULL.getAttribute("loginName")****** return (String) httpSession.getAttribute("loginName"); } }
У меня есть тестовая настройка, как показано ниже
@ExtendWith(SpringExtension.class) @SpringBootTest(classes = { MyWicketApplication.class }) public class ApplicationTest { private WicketTester tester; private final WebApplication webApplication; @Autowired public SecuredWicketGuiApplicationTest(WebApplication application) { this.webApplication = application; } @BeforeEach public void setUp() { //**** ** * WORKS ** ** ** ** // when authenticated is given Authentication authentication = Mockito.mock(Authentication.class); SecurityContext securityContext = Mockito.mock(SecurityContext.class); Mockito.when(securityContext.getAuthentication()).thenReturn(authentication); Mockito.when(authentication.isAuthenticated()).thenReturn(true); SecurityContextHolder.setContext(securityContext); //** ** ** ** ** ** ** ** ** * // and secured session is provided SecureWebSession secureWebSession = Mockito.mock(SecureWebSession.class); //**** ** * WORKS ** ** ** ** // and a superuser role is given Roles roles = new Roles(); roles.add("SUPER_ADMIN"); Mockito.when(secureWebSession.getRoles()).thenReturn(roles); //** ** ** ** ** ** ** ** ** // and session has loginName attribute HttpSession session = Mockito.mock(HttpSession.class); Mockito.when(session.getAttribute("loginName")).thenReturn("test"); HttpServletRequest request = Mockito.mock(HttpServletRequest.class); Mockito.when(request.getSession()).thenReturn(session); tester = new WicketTester(webApplication); MockHttpSession mockHttpSession = new MockHttpSession(null); mockHttpSession.setAttribute("loginName", "test"); // and a requested initiated for a given session MockHttpServletRequest mockedRequest = new MockHttpServletRequest( tester.getApplication(), mockHttpSession, null) { @Override public HttpSession getSession(boolean createNew) { return mockHttpSession; } @Override public HttpSession getSession() { return mockHttpSession; } }; // and a session object is created with a loginName attribute test tester.getRequest().getSession() .setAttribute("loginName", "test"); tester.setRequest(mockedRequest); } @Test public void HomePage_Renders_Successfully() { // then start and render the homePage page tester.startPage(HomePage.class); // assert rendered HomePage component tester.assertRenderedPage(HomePage.class); } }
когда я пытаюсь выполнить этот тест, я застреваю на
public class MyPanel { ... SecureWebSession session = (SecureWebSession) getSession(); lt;--returns a SecuredWebSession Label username = new Label("loginName", session.getLoginName()); lt;-- NullPointerException ... }
Где метод getLoginName определен в securedWebSession
public String getLoginName() { ********RETURNS NULL.getAttribute("loginName")****** return (String) httpSession.getAttribute("loginName"); }
Ответ №1:
Вы создаете несколько объектов с помощью их конструкторов, но они (большинство из них) позже не используются. WicketTester использует переданное приложение для поиска других, т. Е. Использует приложение#NewSession() для создания сеанса Калитки и приложение#newRequest() для создания запроса Калитки. Если вы хотите использовать макетные версии этих приложений, вам нужно создать пользовательское приложение MyTestWebApplication (которое распространяется на приложение MyWicketApplication), переопределить эти методы и настроить его как компонент Spring.
WicketTester использует новый/свежий экземпляр MockHttpServletRequest для каждого запроса. Вы можете получить ссылку на него через tester.getRequest()
и вызвать его #setAttibute() method before actually making the HTTP call (e.g. via
clickLink() ,
executeAjaxEvent() or
StartPage()`).
Таким образом, вы можете просто использовать tester.getHttpSession().setAttribute(..., ...)
его перед выполнением http-вызова.