An end-to-end test on a SpringBoot app

Preamble

Before saying anything about end-to-end testing, I have to talk about annotations. I dislike them. Let me explain. In Java you can label classes and methods with annotations that may mean something to the compiler (those ones aren't a problem), or they may just hang around at runtime so that random magic can happen. For example, if you add @Component to a class it means something like "At startup, create a single instance of this, injecting any necessary dependencies, and then inject this in turn into anything that needs it as a depenency." That always felt to me like too much magic for what is really just a label. It only works if you have a load of Spring dependencies loaded, and there's no reason why some other code couldn't use the same annotation for something completely different - identifying things that should be displayed in a GUI, for example. Different magic, same name! I'd prefer less magic and more explicitness.

Moaning aside, I have to deal with this for work, so let's see how it works for an end-to-end test.

Amble

If you have a SpringBoot app that does restful things over HTTP, you might well want to write a test that starts an instance of the app, sends it an HTTP request, and checks that the right stuff happens. This involves a heap of annotations.

The test class is something like this, assuming that there's a database involved. Everything beginning with @ is an annotation.

// package and imports elided
@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfile("test")
@AutoConfigureMockMvc
class FooTest{
  @Inject MockMvc mvc;

  @Test
  @Sql(scripts={"classpath:fooTestSetup.sql"},executionPhase=Sql.ExecutionPhase.BEFORE_TEST_METHOD)
  void testFooBar(){
    // More mock setup probably goes here...
    var result = mvc.perform(get("/foo/bar"))
      .andExpect(status.ok())
      .andReturn()
      .getResponse()
      .getContentAsString();
    // Now check response body is good...
  }
}

We can assume that you already have SpringBoot as a dependency, but you need to

Postamble

The good part about this is that it works, and you're doing a reasonable simulation of a real request. The bad part is all the dependencies making debugging this stuff hard because it's done automagically.

And mostly I wrote this so that I can come back and read it when I have to do this again.

=> #annotations | #testing

=> back to gemlog

Proxy Information
Original URL
gemini://freeshell.de/gemlog/2022-04-24_An_end_to_end_test_on_a_SpringBoot_app.gmi
Status Code
Success (20)
Meta
text/gemini;lang=en-GB
Capsule Response Time
104.507423 milliseconds
Gemini-to-HTML Time
0.527671 milliseconds

This content has been proxied by September (3851b).