Spring Boot
unit testing
classpath resource
Java
software development

Spring boot How to read resource from classpath in unit test

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Unit tests often need sample JSON, CSV, SQL, or text files that live under src/test/resources. In Spring Boot, the clean approach is to load those files through the classpath instead of hard-coding machine-specific file system paths. That keeps the same test working in local development, CI, and IDE runs.

Where Test Resources Belong

Maven and Gradle both add src/test/resources to the test classpath. That means a file such as src/test/resources/fixtures/user.json can be loaded by name during a test run. You do not need to know the absolute path on disk, and that makes the test portable across laptops and CI runners.

For simple tests, you usually do not need to start the full Spring context just to read a file. Plain Java resource loading is often enough.

Reading a Resource with ClassPathResource

Spring provides ClassPathResource, which is convenient and readable in tests.

java
1import java.nio.charset.StandardCharsets;
2
3import org.junit.jupiter.api.Test;
4import org.springframework.core.io.ClassPathResource;
5
6import static org.junit.jupiter.api.Assertions.assertTrue;
7
8class ResourceTest {
9
10    @Test
11    void readsFixtureFile() throws Exception {
12        ClassPathResource resource = new ClassPathResource("fixtures/user.json");
13        String body = new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
14
15        assertTrue(body.contains(""name""));
16    }
17}

This works well when your test only needs file contents and does not depend on bean wiring.

Reading a Resource Without Spring Context

If you want an even smaller test footprint, use the class loader directly. This is useful in pure unit tests where bringing in @SpringBootTest would be unnecessary overhead.

java
1import java.io.InputStream;
2import java.nio.charset.StandardCharsets;
3
4import org.junit.jupiter.api.Test;
5
6import static org.junit.jupiter.api.Assertions.assertNotNull;
7
8class PlainClasspathTest {
9
10    @Test
11    void loadsFixtureThroughClassLoader() throws Exception {
12        InputStream stream = getClass()
13            .getClassLoader()
14            .getResourceAsStream("fixtures/user.json");
15
16        assertNotNull(stream);
17
18        String body = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
19        System.out.println(body);
20    }
21}

This pattern is often the best choice when the file is just test data and not part of Spring configuration.

Injecting a Resource in a Spring Test

If the test already uses the Spring container, resource injection can make the dependency explicit.

java
1import java.nio.charset.StandardCharsets;
2
3import org.junit.jupiter.api.Test;
4import org.springframework.beans.factory.annotation.Value;
5import org.springframework.boot.test.context.SpringBootTest;
6import org.springframework.core.io.Resource;
7
8import static org.junit.jupiter.api.Assertions.assertTrue;
9
10@SpringBootTest
11class ResourceInjectionTest {
12
13    @Value("classpath:fixtures/user.json")
14    private Resource userFixture;
15
16    @Test
17    void readsInjectedResource() throws Exception {
18        String body = new String(userFixture.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
19        assertTrue(body.contains(""name""));
20    }
21}

This is appropriate when the resource is part of a larger integration-style test. If file access is the only goal, it is heavier than necessary.

Encoding and File Formats

Text resources should usually be read with an explicit charset such as StandardCharsets.UTF_8. Relying on the platform default can create tests that pass locally and fail in CI. For structured files like JSON, it can be useful to parse the content immediately so assertions operate on data instead of raw strings.

Common Pitfalls

  • Using a file system path such as src/test/resources/... directly makes tests brittle because the working directory can change.
  • Starting @SpringBootTest for a simple fixture read slows down tests for no real benefit.
  • Forgetting to place the file under src/test/resources means it never reaches the test classpath.
  • Ignoring character encoding can produce different results on different machines.
  • Not closing streams in longer-lived helper code can leak resources. Short test methods usually rely on process cleanup, but helper utilities should still use try-with-resources.

Summary

  • Put test fixtures under src/test/resources so build tools add them to the classpath.
  • Use ClassPathResource for readable Spring-friendly access in tests.
  • Use getResourceAsStream for lightweight tests that do not need the Spring container.
  • Prefer explicit UTF-8 decoding for text fixtures.
  • Choose the smallest test setup that matches the behavior you are verifying.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.