#事象
spring security test で@AuthenticationPrincipalのアノテーションをつけた引数として持つControllerのテストコードを書いてるのですが、テストを行うと、以下のエラーメッセージが出力されます。AccountUserDetailsクラスのインスタンス化に失敗しているという内容のエラーが出ていると思われるのですが、MockMvcのwith()でuser()にユーザ情報の変数を渡すことで上述したテストができると考えていたのですが、違うのでしょうか。
対処方法を教えていただけないでしょうか。
情報に過不足があれば、ご指摘ください。
#コンソールログ
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.taskmanagement.domain.service.userdetails.AccountUserDetails]: Constructor threw exception; nested exception is java.lang.NullPointerException ・・・省略
#Controller
package com.example.taskmanagement.app.schedule; @Controller @RequestMapping("schedule") public class ScheduleController { ・・・省略 @GetMapping("list") public String list(@AuthenticationPrincipal AccountUserDetails userDetails, Model model) { ・・・省略 return "schedule/list"; } ・・・省略 }
#Test
@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(locations = {"classpath*:META-INF/spring/applicationContext.xml", "classpath*:META-INF/spring/test-context.xml", "classpath*:META-INF/spring/spring-mvc-test.xml"}) @Transactional public class ScheduleControllerTest { @Inject ScheduleController target; private MockMvc mockMvc; private AccountUserDetails userDetails; private SecurityContext securityContext; @Before public void setUp() throws Exception{ mockMvc = MockMvcBuilders.standaloneSetup(target).alwaysDo(log()).build(); } @Test @WithUserDetails(value="user", userDetailsServiceBeanName="accountUserDetailsService") public void testList() throws Exception{ UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken)SecurityContextHolder.getContext().getAuthentication(); userDetails = (AccountUserDetails)authentication.getPrincipal(); mockMvc.perform(get("/schedule/list").with(user(userDetails))) .andDo(print()) .andExpect(status().isOk()) .andReturn(); } }
#AccountUserDetails
package com.example.taskmanagement.domain.service.userdetails; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import com.example.taskmanagement.domain.model.Account; public class AccountUserDetails extends User { private static final long serialVersionUID = 1L; private final Account account; public AccountUserDetails(Account account) { super(account.getUsername(), account.getPassword(), AuthorityUtils .createAuthorityList("ROLE_USER")); this.account = account; } public Account getAccount() { return account; } }
#applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <import resource="classpath:/META-INF/spring/taskmanagement-domain.xml" /> <bean id="passwordEncoder" class="org.springframework.security.crypto.password.DelegatingPasswordEncoder"> <constructor-arg name="idForEncode" value="pbkdf2" /> <constructor-arg name="idToPasswordEncoder"> <map> <entry key="pbkdf2"> <bean class="org.springframework.security.crypto.password.Pbkdf2PasswordEncoder" /> </entry> <entry key="bcrypt"> <bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /> </entry> <!-- When using SCryptPasswordEncoder, you need to add bcprov-jdk15on.jar to the dependency. <entry key="scrypt"> <bean class="org.springframework.security.crypto.scrypt.SCryptPasswordEncoder" /> </entry> --> </map> </constructor-arg> </bean> <context:property-placeholder location="classpath*:/META-INF/spring/*.properties" /> <bean id="beanMapper" class="com.github.dozermapper.spring.DozerBeanMapperFactoryBean"> <property name="mappingFiles" value="classpath*:/META-INF/dozer/**/*-mapping.xml" /> </bean> <!-- Message --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>i18n/application-messages</value> </list> </property> <property name="defaultEncoding" value="UTF-8"></property> </bean> <!-- Exception Code Resolver. --> <bean id="exceptionCodeResolver" class="org.terasoluna.gfw.common.exception.SimpleMappingExceptionCodeResolver"> <!-- Setting and Customization by project. --> <property name="exceptionMappings"> <map> <entry key="ResourceNotFoundException" value="e.xx.fw.5001" /> <entry key="InvalidTransactionTokenException" value="e.xx.fw.7001" /> <entry key="BusinessException" value="e.xx.fw.8001" /> <entry key=".DataAccessException" value="e.xx.fw.9002" /> </map> </property> <property name="defaultExceptionCode" value="e.xx.fw.9001" /> </bean> <!-- Exception Logger. --> <bean id="exceptionLogger" class="org.terasoluna.gfw.common.exception.ExceptionLogger"> <property name="exceptionCodeResolver" ref="exceptionCodeResolver" /> </bean> <!-- Filter. --> <bean id="exceptionLoggingFilter" class="org.terasoluna.gfw.web.exception.ExceptionLoggingFilter" > <property name="exceptionLogger" ref="exceptionLogger" /> </bean> </beans>
#test-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder location="classpath*:/META-INF/spring/*.properties" /> <!-- (1) --> <bean id="exceptionLogger" class="org.terasoluna.gfw.common.exception.ExceptionLogger" /> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> <!-- (2) --> <bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> </beans>
#spring-mvc-test.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <context:component-scan base-package="com.example.taskmanagement" /> </beans>
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。