Docs

Documentation versions (currently viewingVaadin 25.4 (pre-release))

Spring Test Lifecycle

The order in which Spring and the browserless environment set up a test, and how it affects session-scoped beans and authentication.

A Spring browserless test creates the mocked Vaadin environment after Spring has prepared the test instance. The order of these steps determines when dependency injection and authentication become available, which affects session-scoped beans and authentication that a test changes later. Plain Java and Quarkus tests use their own framework setup, and the Java EE/CDI integration has its own Weld lifecycle.

Order of Test Setup

With an application context that a test configuration defines as a bean, the sequence is:

  1. Spring creates the browserless application context when it starts the Spring application context, before the first test that uses it. Later tests with the same Spring configuration reuse both.

  2. JUnit creates the test instance and Spring injects its @Autowired fields, including the browserless application context. No Vaadin session exists yet.

  3. The test’s @BeforeEach method, or the test method itself, creates a user and opens a window. For a secured context, the user’s authentication is installed when the test creates the user. The window creates its UI and navigates to the root route.

  4. The test closes the user in an @AfterEach method, or at the end of the test method. Spring closes the browserless application context when it closes the Spring application context.

With an application context that the test creates itself, the test’s @BeforeEach method creates the context from the autowired Spring ApplicationContext, and its @AfterEach method closes it, together with all users and windows.

For SpringBrowserlessTest, the default sequence is:

  1. JUnit creates the test instance and Spring injects its @Autowired fields, before the Vaadin environment exists.

  2. JUnit extension callbacks run. With their default timing, Spring Security test annotations populate SecurityContextHolder.

  3. The base class’s @BeforeEach method creates the Vaadin service, session, and UI and navigates to the root route.

  4. Subclass @BeforeEach methods and the test method can use that environment.

  5. The inherited cleanup closes the Vaadin environment after the test.

In both cases, the environment is available after its setup, not during initial test-instance injection. See Test Environment and Lifecycle for the common APIs.

Session-Scoped Beans

Resolving a @VaadinSessionScope bean during test-instance injection fails because no Vaadin session exists yet. This failure affects every test in the class, including methods that do not use the field. An ObjectProvider defers resolution until getObject() is called after environment setup. A lazy proxy with @Lazy, or an ApplicationContext.getBean() call made after setup, can also defer lookup.

Spring’s @SessionScope beans don’t fail during test-instance injection. Spring’s test support binds a mock request and session before injecting the test instance, and the default scoped proxy resolves the bean when it’s used. Deferred lookup works for these beans too.

Views created during initial or explicit navigation already have the Vaadin environment available, so their session-scoped dependencies can resolve then. In multi-user Spring tests, request- and session-scoped beans resolve for the active user; activate the intended window before resolving a bean directly.

For a complete test, see Access Session-Scoped Beans.

Authentication Applied During a Test

A secured application context installs each user’s authentication before the user’s windows open, and in SpringBrowserlessTest, Spring Security’s @WithMockUser, @WithAnonymousUser, and @WithUserDetails establish authentication before the environment’s initial navigation, with their default timing. View access control therefore observes the simulated user during that navigation.

Authentication established in the test body, or with setupBefore = TestExecutionEvent.TEST_EXECUTION in a base-class test, arrives after initial navigation. Subsequent requests use that authentication, but getCurrentView() still returns the previously rendered view until another navigation takes place.

Page.reload() recreates the UI at the currently active location. If initial navigation redirected to the login view, reloading renders the login location again; it does not navigate to the original protected destination.

For a worked Spring test, see Navigate after Changing Authentication. See Spring Security Integration for setup requirements and session ID rotation.

4B6C9E13-7A85-42D0-9F3B-1C8E5D4A2B76