我将easymock与Spring项目集成在一起,并执行了大多数单元测试。但是遇到了无法模拟超级方法的问题。当我运行测试类时,它说不支持该方法。
I integrated easymock with my Spring project and performed most of the unit tests. But got an issue with not able to mock the super method. When I run my test class it says method not supported.
任何想法都出了什么问题,因为我在过去的几天里尽力而为,没有任何线索如何模拟超级方法。
Any idea what's going wrong as I tried my best for last couple of days and not able to get any clue on how to mock the super method.
org.springframework.security.authentication.AuthenticationServiceException: Authentication method not supported: at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:71) at com.dashboard.core.CustomAuthenticationFilter.attemptAuthentication(CustomAuthenticationFilter.java:20) at com.dashboard.core.CustomAuthenticationFilterTest.testAttemptAuthentication(CustomAuthenticationFilterTest.java:64)要测试的类:
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apachemons.lang.StringUtils; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.dashboard.domain.ApplicationConstant; public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){ String username = request.getParameter("j_username"); String password = request.getParameter("j_password"); if(isValidUsername(username) && isValidPassword(password) ){ return super.attemptAuthentication(request, response); } throw new BadCredentialsException(ApplicationConstant.CREDENTIALS_NOT_FORMAT.getValue()); } private static boolean isValidUsername(String username){ return !StringUtils.isEmpty(username) && username.matches(ApplicationConstant.USERNAME_PATTERN.getValue()); } private static boolean isValidPassword(String password){ return !StringUtils.isEmpty(password) && password.matches(ApplicationConstant.PWD_PATTERN.getValue()); } }我的测试班:
import java.util.ArrayList; import java.util.List; import org.easymock.EasyMock; import org.easymock.EasyMockRunner; import org.easymock.EasyMockSupport; import org.easymock.Mock; import org.easymock.TestSubject; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @RunWith(EasyMockRunner.class) public class CustomAuthenticationFilterTest extends EasyMockSupport{ @TestSubject CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(); @Mock UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter; @Test public void testAttemptAuthentication() throws Exception{ MockHttpServletRequest request = new MockHttpServletRequest(); request.setParameter("j_username", "Sundar1234"); request.setParameter("j_password", "Sundar1234$$"); MockHttpServletResponse response = new MockHttpServletResponse(); SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER"); List<SimpleGrantedAuthority> updatedAuthorities = new ArrayList<SimpleGrantedAuthority>(); updatedAuthorities.add(authority); User user = new User("Sundar1234", "Sundar1234$$", updatedAuthorities); Authentication auth = new UsernamePasswordAuthenticationToken(user,null); EasyMock.expect(usernamePasswordAuthenticationFilter.attemptAuthentication(request, response)).andReturn(auth); EasyMock.replay(usernamePasswordAuthenticationFilter); Assert.assertNotNull(customAuthenticationFilter.attemptAuthentication(request, response)); EasyMock.verify(usernamePasswordAuthenticationFilter); } }推荐答案
UsernamePasswordAuthenticationFilter 是基类,而不是注入的依赖项。通常,您可以使用部分模拟解决此问题。但是,由于 CustomAuthenticationFilter 调用了无法嘲笑的 super.attemptAuthentication ,您不能这样做。
UsernamePasswordAuthenticationFilter is a base class, not an injected dependency. Normally, you can workaround that by using a partial mock. But you can't since CustomAuthenticationFilter is calling super.attemptAuthentication which can't be mocked.
您的解决方案是:
但是由于当前的春季对于此类过滤器的设计,委托似乎笨拙。因此,总的来说,测试是您最好的选择。
But because of the current Spring design for such filter, delegating seems clunky. So testing altogether is I think your best bet.
更多推荐
使用easymock / powermock模拟超级方法调用
发布评论