> Markdown version of [Spring Test Lifecycle](https://vaadin.com/docs/next/flow/testing/browserless/environment-differences). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Spring Test Lifecycle

`SpringBrowserlessTest` 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](https://vaadin.com/docs/next/flow/testing/browserless/cdi.md) has its own Weld lifecycle.

## <a id="test-lifecycle"></a>Order of Test Setup

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.

The environment is therefore available after its setup hook, not during initial test-instance injection. See [Test Environment and Lifecycle](https://vaadin.com/docs/next/flow/testing/browserless/test-environment.md) for the common APIs.

## <a id="session-scoped-beans"></a>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](https://vaadin.com/docs/next/flow/testing/browserless/multi-user.md#pitfalls-and-guarantees), 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](https://vaadin.com/docs/next/building-apps/testing/browserless/setup-spring-boot.md#session-scoped-beans).

## <a id="authentication-applied-during-a-test"></a>Authentication Applied During a Test

With their default timing, Spring Security’s `@WithMockUser`, `@WithAnonymousUser`, and `@WithUserDetails` establish authentication before the environment’s initial navigation. View access control therefore observes the simulated user during that navigation.

Authentication established in the test body, or with `setupBefore = TestExecutionEvent.TEST_EXECUTION`, 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](https://vaadin.com/docs/next/building-apps/testing/browserless/test-view-access.md#authentication-applied-during-a-test). See [Spring Security Integration](https://vaadin.com/docs/next/flow/testing/browserless/spring-security.md) for setup requirements and session ID rotation.

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