问题描述
我正在从头开始创建一个新的 Spring Boot 应用程序,并想为其编写测试.我刚刚在我的应用中实施了身份验证,并想了解角色的工作原理.
I'm creating a new Spring Boot app from the scratch and want to write tests for it. I've just implemented authentication into my app and want to learn how roles work.
当我在身份验证过程中使用我的 UserRepository 时,一切正常.但是,当我想在测试中使用 UserRepository 时,它说该对象为空,这与我在应用程序代码中使用它时一样.这是为什么?这是代码.
When I use my UserRepository in the authentication process, everything works as it should. However, when I want to use UserRepository in tests, it says that the object is null, the same one that's OK when I use it in the app code. Why is that?Here's the code.
安全配置类:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PowderizeUserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout().permitAll();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManager) {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setPasswordEncoder(passwordEncoder());
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationManager.authenticationProvider(authenticationProvider);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}
用户类别:
@Entity
@Table(name = "USERS")
@NoArgsConstructor
@Getter
public class User extends BaseEntity {
private String firstName;
private String lastName;
private String emailAddress;
private String nickname;
private String password;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
@ManyToMany(mappedBy = "users_roles")
private Set<Role> roles;
}
存储库:
public interface UserRepository extends CrudRepository<User, Long> {
public Optional<User> findByEmailAddress(String email);
}
UserDetailsService 实现类,使用存储库没有问题:
UserDetailsService implementation class, that uses the repository with no problems:
@Service
public class PowderizeUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return new PowderizePrincipal(
userRepository.findByEmailAddress(email)
.orElseThrow(() -> new UsernameNotFoundException("User '" + email + "' not found."))
);
}
}
以及返回 NullPointerException 的测试类:
And the test class that returns NullPointerException:
@SpringBootTest
public class UsersAndRolesTest {
@Autowired
private UserRepository userRepository;
@Test
public void ww(){
assertThat(userRepository, notNullValue());
}
@Test
public void userExistsInDatabase(){
assertThat(userRepository.findByEmailAddress("[email protected]").isPresent(), notNullValue());
}
}
我尝试过使用@Repository、@EnableJpaRepositories 等注释,实际上我找到的每个解决方案.IntelliJ 还突出显示了 userRepository
并带有无法自动装配.未找到‘UserRepository’类型的 bean."
I've tried using annotations like @Repository, @EnableJpaRepositories, actually every solution I've found. IntelliJ also highlights the userRepository
with "Could not autowire. No beans of 'UserRepository' type found."
推荐答案
在 vanillaSugar 的回答的指导下,我找到了解决方案.我缺少的是 @RunWith(SpringRunner.class)
注释,但这还不够.我意识到问题也与测试套件所在的包有关.我没有在问题中添加 package
代码行,这也是问题的一部分.
I've found the solution, guided by vanillaSugar's answer. What I was lacking was the @RunWith(SpringRunner.class)
annotation, but it was not enough. I've realized that the problem was also connected to the package the test suite was located. I didn't add the package
line of code in the question, and it was the part of the problem as well.
根据我的发现,@SpringBootApplication
在应用程序的包层次结构中扫描它下面的组件.只是添加 @RunWith
注释使我遇到了另一个异常的问题:java.lang.IllegalStateException:无法找到@SpringBootConfiguration,您需要在测试中使用@ContextConfiguration 或@SpringBootTest(classes=...)
.
From what I've found, @SpringBootApplication
scans for components below it in the package hierarchy in the app. Just adding @RunWith
annotation led me to this problem with another exception:java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
.
我还必须做的是将我的测试类从以前的包 - security.UsersAndRolesTest
移动到 com.powderize.security.UsersAndRolesTest
,它镜像"了应用程序代码中的包.对于更高级的 Spring 开发人员来说可能很明显,但我花了一段时间才发现它.
What I also had to do is to move my test class from previous package - security.UsersAndRolesTest
to com.powderize.security.UsersAndRolesTest
, which "mirrors" the packages in the app code. Probably obvious for more advanced Spring developers, but took me a while to discover it.
这篇关于Spring Data 存储库无法自动装配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!