wicket 9: 单元测试 + mockito + httpSession
wicket 9: unit testing + mockito + httpSession
情况
我正在使用 wicket 9 进行 web gui 开发。现在我正在尝试通过模拟(mockito)非必需的方法来进行一些 junit 测试。其中一种方法是
httpSession.getAttribute("loginName");
这样调用的:
public class MyPanel {
...
SecureWebSession session = (SecureWebSession) getSession(); <--returns a SecuredWebSession
Label username = new Label("loginName", session.getLoginName()); <-- NullPointerException
...
}
显然,我嘲笑事物的方式有些不对。我希望它进行 return 测试,但我始终得到 NullPointerException。
我的问题是如何绕过 session.getLoginName() 以便调用 return
登录名测试?
如何在测试 wicket 应用程序时模拟 httpSession?
详情
我有一个 securedWebSession class
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(); <--returns a SecuredWebSession
Label username = new Label("loginName", session.getLoginName()); <-- NullPointerException
...
}
在 securedWebSession 中定义方法 getLoginName 的地方
public String getLoginName() {
********RETURNS NULL.getAttribute("loginName")******
return (String) httpSession.getAttribute("loginName");
}
您通过它们的构造函数创建了几个对象,但它们(其中大部分)以后不会使用。 WicketTester 使用传递的应用程序来查找其他应用程序,即它使用 application#newSession() 创建 Wicket 会话,并使用 application#newRequest() 创建 Wicket 请求。如果你想使用这些的模拟版本,那么你需要创建一个自定义的 MyTestWebApplication(从 MyWicketApplication 扩展),覆盖这些方法并将其设置为 Spring bean。
WicketTester 为每个请求使用一个 new/fresh MockHttpServletRequest 实例。您可以通过 tester.getRequest()
获取对它的引用并调用其 #setAttibute()method before actually making the HTTP call (e.g. via
clickLink(),
executeAjaxEvent()or
startPage()`).
因此您可以在进行 http 调用之前使用 tester.getHttpSession().setAttribute(..., ...)
。
情况
我正在使用 wicket 9 进行 web gui 开发。现在我正在尝试通过模拟(mockito)非必需的方法来进行一些 junit 测试。其中一种方法是
httpSession.getAttribute("loginName");
这样调用的:
public class MyPanel {
...
SecureWebSession session = (SecureWebSession) getSession(); <--returns a SecuredWebSession
Label username = new Label("loginName", session.getLoginName()); <-- NullPointerException
...
}
显然,我嘲笑事物的方式有些不对。我希望它进行 return 测试,但我始终得到 NullPointerException。
我的问题是如何绕过 session.getLoginName() 以便调用 return 登录名测试?
如何在测试 wicket 应用程序时模拟 httpSession?
详情
我有一个 securedWebSession class
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(); <--returns a SecuredWebSession
Label username = new Label("loginName", session.getLoginName()); <-- NullPointerException
...
}
在 securedWebSession 中定义方法 getLoginName 的地方
public String getLoginName() {
********RETURNS NULL.getAttribute("loginName")******
return (String) httpSession.getAttribute("loginName");
}
您通过它们的构造函数创建了几个对象,但它们(其中大部分)以后不会使用。 WicketTester 使用传递的应用程序来查找其他应用程序,即它使用 application#newSession() 创建 Wicket 会话,并使用 application#newRequest() 创建 Wicket 请求。如果你想使用这些的模拟版本,那么你需要创建一个自定义的 MyTestWebApplication(从 MyWicketApplication 扩展),覆盖这些方法并将其设置为 Spring bean。
WicketTester 为每个请求使用一个 new/fresh MockHttpServletRequest 实例。您可以通过 tester.getRequest()
获取对它的引用并调用其 #setAttibute()method before actually making the HTTP call (e.g. via
clickLink(),
executeAjaxEvent()or
startPage()`).
因此您可以在进行 http 调用之前使用 tester.getHttpSession().setAttribute(..., ...)
。