1

I'm trying to test some services in Micronaut which do not need a datasource connection but if there is a datasource configured in the application.yml then running a @MicronautTest connects to the database.

application.yml

# ...
datasources:
  default:
    url: 
    username:
    password:
# ...

a dummy controller which returns Okay 200:

@Controller("/api/heartbeat")
class HeartbeatController {

    @Get("/")
    fun getHeartbeat(): HttpResponse<Unit> = HttpResponse.ok()
}

controller spec:

@MicronautTest
class HeartbeatControllerSpec {

    @Inject
    @field:Client("/")
    lateinit var client: HttpClient

    @Test
    fun `Given the heartbeat endpoint, when it is called, then it should return Ok`() {
        val rsp = client.toBlocking()
            .exchange<Unit>("/api/heartbeat")
        assertEquals(HttpStatus.OK, rsp.status)
    }
}

The issue I'm having is the above test fails if there's no database configured because the application still tries to connect to a database as long as the datasources config exists in the application.yml.

I've tried @MicronautTest(startApplication = false) but it doesn't make a difference.

For my 'unit tests', I solved this issue by not annotating the test with @MicronautTest and initializing the service under test manually but in this case this is not possible because I'd like to call the controller with the HTTP client.

Is there a way to run application tests while at the same time not allowing the app to connect to a db?

Archmede
  • 1,592
  • 2
  • 20
  • 37
  • 2
    I know your question is "Is there a way to run application tests while at the same time not allowing the app to connect to a db?" and this does not address that question but a common approach is to define an in memory database in `application-test.yml` which overrides the default one defined in `application.yml`. – Jeff Scott Brown May 03 '21 at 23:18
  • @JeffScottBrown I have tried in memory dbs but I don't want to define two ymls, one for tests that don't use a db and one for tests that do. – Archmede May 04 '21 at 13:24
  • 1
    "I have tried in memory dbs but I don't want to define two ymls, one for tests that don't use a db and one for tests that do." - There are many good reasons to have more than 1 yml config file in a Micronaut service and an aversion to that will complicate a lot of systems. Unclear if yours is one of those. – Jeff Scott Brown May 04 '21 at 13:31
  • I agree with Jeff that this is a very common approach. When using a @MicronautTest it will try to create a DataSource. Just another suggestion, which also does not directly answer your question, but have you heard of "Property Value Placeholders"? https://docs.micronaut.io/1.3.0.M1/guide/index.html#_property_value_placeholders – abedurftig May 17 '21 at 09:56
  • "Is there a way to run application tests while at the same time not allowing the app to connect to a db?" - The answer to the question is "yes" but a comment above indicates that you have a preference to only have 1 `.yml` config file. Are you opposed to introducing a separate config file that is not a `yml` file (`application-test.properties`, for example)? – Jeff Scott Brown May 17 '21 at 13:23
  • 1
    Another option is to override your database config settings in every test that doesn't want to connect to the database. That is going to be very tedious, but an option. Another is to mark all of your beans that trigger database interaction with something like `@Requires(notEnv="test")`. There are a number of tedious ways to deal with only 1 config file, but separate config files really shouldn't be something you strive to avoid. We support loading multiple config to simplify scenarios like this. – Jeff Scott Brown May 18 '21 at 12:48
  • I decided to separate my tests into unit tests, and system tests. unit tests don't need to application context as dependencies are mocked(No need to MicronautTest annotation). System tests will need a db connection wether or not they need to connection – Archmede May 18 '21 at 16:06

0 Answers0