6

I didn't want to load the entire Spring Boot configuration for unit-testing my DAO layer, and therefore created a nested configuration class to suppress default configurations. But when I try to specify SQL scripts for it to run before tests, its unable to find them.

Here's the code:

package com.test.customer.controller;
..
@RunWith(SpringRunner.class)
@JdbcTest
@Sql({"data.sql"})
public class InterviewInformationControllerTest {

    @Configuration
    static class TestConfiguration{

    }

    @Test
    public void testCustomer() {
        // code
    }

}

I get the error:

Cannot read SQL script from class path resource [com/test/customer/controller/data.sql]; 
nested exception is java.io.FileNotFoundException: 
class path resource [com/test/customer/controller/data.sql] 
cannot be opened because it does not exist

I've tried placing the file at both src/main/resources (not preferred) as well as at src/test/resources (which I prefer)

Note: I'm running the Unit test from inside Eclipse by doing Run as -> JUnit test.

Edit: Added the static keyword to the configuration class

Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
Daud
  • 7,429
  • 18
  • 68
  • 115

2 Answers2

24

your inner configuration class will not work unless you add a static keyword before its definition. However you should know that for the @Sql annotation

Path Resource Semantics

Each path will be interpreted as a Spring Resource. A plain path — for example, "schema.sql" — will be treated as a classpath resource that is relative to the package in which the test class is defined. A path starting with a slash will be treated as an absolute classpath resource, for example: "/org/example/schema.sql". A path which references a URL (e.g., a path prefixed with classpath:, file:, http:, etc.) will be loaded using the specified resource protocol.

So try to prefix the value inside @Sql with classpath: like this :

@Sql(scripts={"classpath:data.sql"})

Good luck!

Abdelghani Roussi
  • 2,707
  • 2
  • 21
  • 39
  • 1
    Will **src/main/resources** and **src/test/resources** both be included in the classpath by default? – Daud Mar 13 '19 at 14:33
  • Sometimes vanilla java don't add the src/main/resources to the classpath depending on the runner that you are using – Abdelghani Roussi Mar 13 '19 at 14:37
  • 1
    +1 for path resource semantics. @Daud, you may want to check out [this](https://stackoverflow.com/questions/29669393/override-default-spring-boot-application-properties-settings-in-junit-test/60296719#60296719) for your question on resources. – jumping_monkey Jun 07 '20 at 03:17
3

Check your out directory of the module. While creating directory in resources, if you have named it directly with the namespace like com.gakshintala.bookmybook, it takes that name completely as the directory name, so the out also contains this directory under resources with name com.gakshintala.bookmybook. PFB right vs wrong. The top is right and bottom is wrong.

enter image description here enter image description here

Spring always looks for nested directory resources->com->gakshintala->bookmybook. So create that directory structure.

Gopal S Akshintala
  • 1,933
  • 1
  • 17
  • 24