Skip to content

WithMockUser does not work when running tests in a native image #12189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wilkinsona opened this issue Nov 10, 2022 · 1 comment
Closed

WithMockUser does not work when running tests in a native image #12189

wilkinsona opened this issue Nov 10, 2022 · 1 comment
Assignees
Labels
in: test An issue in spring-security-test type: bug A general bug

Comments

@wilkinsona
Copy link
Member

Describe the bug
If @WithMockUser is used in a test that is run in a native image, it will fail as WithMockUserSecurityContextFactory cannot be instantiated due to missing reflection hints:

2022-11-09T22:23:27.680Z  WARN 836 --- [           main] o.s.test.context.TestContextManager      : Caught exception while invoking 'beforeTestMethod' callback on TestExecutionListener [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@2d8b79e9] for test method [public void com.example.security.thymeleaf.SecurityThymeleafApplicationTests.accessSecuredResourceAuthenticatedThenOk() throws java.lang.Exception] and test instance [com.example.security.thymeleaf.SecurityThymeleafApplicationTests@5a7a2dec]	
java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.test.context.support.WithMockUserSecurityContextFactory': Failed to instantiate [org.springframework.security.test.context.support.WithMockUserSecurityContextFactory]: No default constructor found	
	at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createFactory(WithSecurityContextTestExecutionListener.java:176) ~[security-thymeleaf-tests:6.0.0-RC2]	
	at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createTestSecurityContext(WithSecurityContextTestExecutionListener.java:134) ~[security-thymeleaf-tests:6.0.0-RC2]	
	at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createTestSecurityContext(WithSecurityContextTestExecutionListener.java:113) ~[security-thymeleaf-tests:6.0.0-RC2]	
	at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.beforeTestMethod(WithSecurityContextTestExecutionListener.java:81) ~[security-thymeleaf-tests:6.0.0-RC2]	
	at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:294) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.test.context.junit.jupiter.SpringExtension.beforeEach(SpringExtension.java:174) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$2(TestMethodTestDescriptor.java:166) ~[security-thymeleaf-tests:5.9.1]	
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:202) ~[security-thymeleaf-tests:5.9.1]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:202) ~[security-thymeleaf-tests:5.9.1]	
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:165) ~[security-thymeleaf-tests:5.9.1]	
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:132) ~[security-thymeleaf-tests:5.9.1]	
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) ~[security-thymeleaf-tests:5.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[na:na]	
	at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511) ~[security-thymeleaf-tests:na]	
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[na:na]	
	at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511) ~[security-thymeleaf-tests:na]	
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[na:na]	
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[security-thymeleaf-tests:1.9.1]	
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147) ~[na:na]	
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127) ~[na:na]	
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90) ~[na:na]	
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55) ~[na:na]	
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102) ~[na:na]	
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54) ~[na:na]	
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[na:na]	
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95) ~[na:na]	
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91) ~[na:na]	
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60) ~[na:na]	
	at org.graalvm.junit.platform.NativeImageJUnitLauncher.execute(NativeImageJUnitLauncher.java:74) ~[na:na]	
	at org.graalvm.junit.platform.NativeImageJUnitLauncher.main(NativeImageJUnitLauncher.java:129) ~[na:na]	
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.test.context.support.WithMockUserSecurityContextFactory': Failed to instantiate [org.springframework.security.test.context.support.WithMockUserSecurityContextFactory]: No default constructor found	
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1306) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1198) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:321) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createFactory(WithSecurityContextTestExecutionListener.java:170) ~[security-thymeleaf-tests:6.0.0-RC2]	
	... 55 common frames omitted	
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.test.context.support.WithMockUserSecurityContextFactory]: No default constructor found	
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) ~[security-thymeleaf-tests:6.0.0-RC4]	
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1300) ~[security-thymeleaf-tests:6.0.0-RC4]	
	... 60 common frames omitted	
Caused by: java.lang.NoSuchMethodException: org.springframework.security.test.context.support.WithMockUserSecurityContextFactory.<init>()	
	at [email protected]/java.lang.Class.getConstructor0(DynamicHub.java:3585) ~[security-thymeleaf-tests:na]	
	at [email protected]/java.lang.Class.getDeclaredConstructor(DynamicHub.java:2754) ~[security-thymeleaf-tests:na]	
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:79) ~[security-thymeleaf-tests:6.0.0-RC4]	
	... 61 common frames omitted

To Reproduce
Run ./gradlew security:security-thymeleaf:nativeTest in the AOT smoke tests.

Expected behavior
@WithMockUser and other @With… annotations work in native tests.

I suspect that AOT processing needs to look for any @WithSecurityContext (meta-)annotations and add reflection hints for their factory.

Sample
https://github.com/spring-projects/spring-aot-smoke-tests/tree/c8628f7baa5aa1c894bfe4a17706d7cdd218509f/security/security-thymeleaf

@wilkinsona wilkinsona added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 10, 2022
@marcusdacoregio marcusdacoregio self-assigned this Nov 11, 2022
@marcusdacoregio marcusdacoregio added in: test An issue in spring-security-test and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 11, 2022
@marcusdacoregio marcusdacoregio added this to the 6.0.0 milestone Nov 11, 2022
@marcusdacoregio marcusdacoregio changed the title WithMockUser does not work when running tests in a native image Add native support for annotations using @WithSecurityContext Nov 16, 2022
@marcusdacoregio marcusdacoregio changed the title Add native support for annotations using @WithSecurityContext WithMockUser does not work when running tests in a native image Nov 16, 2022
@marcusdacoregio
Copy link
Contributor

Thanks @wilkinsona, I'll close this in favor of #12215

@marcusdacoregio marcusdacoregio removed this from the 6.0.0 milestone Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test An issue in spring-security-test type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants