- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在开发 Spring Web 应用程序时,我只是第一次实现了 Spring Security,为了简单起见,我现在使用一个有权访问站点某些部分的单个用户。它工作得很好,但我无法弄清楚我如何用 Junit5/Mockito 测试它。安全配置文件如下所示;
@Configuration
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserService userService;
@Autowired
public AppSecurityConfig(UserService userService) {
this.userService = userService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "/css/*", "/js/*", "/images/*", "/site/*")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
}
@Override
protected UserDetailsService userDetailsService() {
UserDetails user = userService.loadUserByUsername("admin");
return new InMemoryUserDetailsManager(user);
}
}
userService 是一个只有一个方法的接口(interface);
public interface UserService {
UserDetails loadUserByUsername(String s);
}
它的实现类是;
@Service
public class UserServiceImpl implements UserDetailsService, UserService {
private final UserRepository userRepository;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findByUsername(s);
if(user == null) {
throw new UsernameNotFoundException(s);
}
return new UserDetailsWrapper(user);
}
}
我只是想通过一个简单的集成测试来运行它,该测试正在模拟 UserService 及其 loadUserByUsername() 方法;
@SpringBootTest
class SiteApplicationTests {
@Mock
private UserService userService;
@BeforeEach
void setUp() {
}
@Test
void contextLoads() {
// "testpassword"
String hashedPassword = "$2y$12$LoUoUX4t54/gDGDNvNf6w.hBhpVffPdoI3lZG0P0bVvEnBRVCsw5i";
UserDetails user = User.builder()
.username("admin")
.password(hashedPassword)
.build();
when(userService.loadUserByUsername(any(String.class))).thenReturn(user);
}
}
但这失败并出现以下错误;
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:341)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:346)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:341)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:340)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:263)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:256)
at java.base/java.util.Optional.orElseGet(Optional.java:369)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:255)
at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:29)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:108)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:107)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:107)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:107)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:75)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.core.userdetails.UsernameNotFoundException: admin
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:483)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:311)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
... 63 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.core.userdetails.UsernameNotFoundException: admin
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650)
... 84 more
Caused by: org.springframework.security.core.userdetails.UsernameNotFoundException: admin
at com.bringbackdada.site.services.UserServiceImpl.loadUserByUsername(UserServiceImpl.java:24)
at com.bringbackdada.site.security.AppSecurityConfig.userDetailsService(AppSecurityConfig.java:39)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.createSharedObjects(WebSecurityConfigurerAdapter.java:430)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:204)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:322)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:94)
at com.bringbackdada.site.security.AppSecurityConfig$$EnhancerBySpringCGLIB$$2bf2a294.init(<generated>)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:370)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:324)
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:104)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 85 more
我很清楚,Spring 找不到用户,因为底层数据库不存在,这也是它在跟踪中所说的。我也在这里猜测,作为 Spring 的新手,也许测试方法是在应用程序上下文之后加载的,而配置不是,因此不能像我显然没有做的那样被 mock 。但是我找不到任何关于如何在这个特定的上下文中模拟 Spring Security 的实际配置的引用。请帮忙!
最佳答案
问题是你应该使用 @MockBean
为 UserService
创建模拟 bean 的注释并将其注入(inject)应用程序上下文中,@Mock
注释用于单元测试,而不是用于 Spring Boot 集成测试
@SpringBootTest
class SiteApplicationTests {
@MockBean
private UserService userService;
@BeforeEach
void setUp() {
}
@Test
void contextLoads() {
// "testpassword"
String hashedPassword = "$2y$12$LoUoUX4t54/gDGDNvNf6w.hBhpVffPdoI3lZG0P0bVvEnBRVCsw5i";
UserDetails user = User.builder()
.username("admin")
.password(hashedPassword)
.build();
when(userService.loadUserByUsername(any(String.class))).thenReturn(user);
}
}
关于java - 如何将 SpringBootTest 与 Web 安全和 Service usnig Junit5 和 Mockito 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64035113/
我有一个具有以下结构的 Spring Boot 项目 src |--- main | |--- java | | |--- io.example.config | | |
目录 SpringBootTest 踩坑 SpringBootTest的一个小坑注意点 1、我当时运行SpringBoot测试类的时候踩这个坑
我靠@SpringBootTest在测试应用程序配置时非常重要。应用程序属性可能很复杂,具有默认值和重要的验证。例如: prop: ports: 1205,2303,4039 fqdn: ${
我正在使用 jasypt 加密 Spring Boot 应用程序中的 application.properties。我的目标是更新我的集成测试,以便 jasypt 与测试加密器密码一起使用。我的问题是
使用基于 Spring Boot 和 MongoDB 的一些端点实现微服务,并尝试使用 @SpringBootTest 注释功能编写集成测试. 目前,我面临一个问题,我需要预先填充一个嵌入式 Mong
我有一个类似于以下的代码: @RunWith(SpringRunner.class) @SpringBootTest public class ModelRunnerTest { @Autow
我的 SpringBootTest 注释无法解析为类型。这里有同样的问题,但似乎添加依赖项 org.springframework.boot spring-boot-starter-
我有一个带有数据库和 rabbitmq 用法的小型 Spring Boot 应用程序。 所以我想用集成测试(H2 + apache qpid)进行测试。 @ExtendWith(SpringExten
这就是单元测试的正确本质吗?我想我不明白我应该测试什么。 ConverterContext是一个策略类 @SpringBootTest @ExtendWith(SpringExtension.clas
我有一个正在测试 spring 应用程序部分的测试。它使用 SpringRunner 和注解 @SpringBootTest 所以它启动了一个完整的 spring 服务器。 问题是测试是由无法访问数据
我如何引导我的 Spring Boot 2 集成测试,以便在所有这些测试中我可以拥有一组配置,这些配置使用一些可用于所有集成测试的测试数据预先植入测试数据库? 最佳答案 假设您正在使用 h2 测试数据
目录 @SpringBootTest单元测试的坑 1、环境 2、遇到的问题 3、解决方式 Test类运行单元测试
我正在尝试在“干净”的上下文中运行 @SpringBootTest,而不执行 MyApplicationContextInitializer。 MyApplicationContextInitiali
我正在构建一个 Spring Boot 应用程序。我想像这样运行它: java -jar myjar.jar inputFile outputFile 我该如何写 @SpringBootTest为了
我有一个 @SpringBootTest 用于在服务器上执行集成测试。根据配置,我希望服务器的行为有所不同。配置本身由我的应用程序逻辑深处的 beans (scope = singleton) 读取,
我有一个带有 hibernate 功能的 SpringBoot 应用程序。在我的测试中,我想禁用任何类型的数据库连接和配置(测试无权访问数据库)。我该怎么做? 我的测试类用 @SpringBootTe
我想测试我的 WebSocket 应用程序。 测试类: @RunWith(SpringRunner.class) @SpringBootTest( webEnvironment = Sprin
我写了一个 ApplicationListener 应该检查环境是否在上下文初始化期间准备好。我在测试场景时遇到了麻烦,因为我在 configure() 和 main() 方法中手动添加了监听器。 应
我有一个简单的 Spring Boot 项目。 我正在使用 maven 进行依赖管理。 导入为 SpringBootTest不被认可,所以我得到: SpringBootTest cannot be r
我目前正在努力解决 SpringBootTest 实例的服务器端口注入(inject)问题。我编写了一个测试配置类,我想在其中访问此端口。 测试配置类: @Target(AnnotationTarge
我是一名优秀的程序员,十分优秀!