hamvocke / spring-testing

A Spring Boot application with lots of test examples
https://www.martinfowler.com/articles/practical-test-pyramid.html
1.09k stars 430 forks source link

Consider removing all entries from the database before the test is executed #1

Closed wbiller closed 8 months ago

wbiller commented 6 years ago

To make sure you don't run into any trouble (e.g. a corrupt state) it's always a good idea to remove any existing data before integration tests and e2e tests are executed.

From my experience it's a bit frustrating to do this in every test and for every entity that is handled by the tests, as you have to autowire each Repository and call the deleteAll() method. Fortunately there's SQL and Spring provides the @org.springframework.test.context.jdbc.Sql annotation, which allows you to execute SQL before a test.

So you can create a file containing nothing else than delete statements and have this executed before each test.

delete-all.sql

delete from Person;

SomeIntegrationTest.java

//... package, imports etc.

@Sql(scripts ="/delete-all.sql")
public class SomeIntegrationTest { }
hamvocke commented 6 years ago

That's a nifty trick, I didn't know about that one.

Cleaning up state is something that becomes a necessity quite soon once you start more sophisticated tests. I'm a little torn here between keeping things simple, YAGNI and preventing that others will run into this issue. After all, right now this codebase doesn't need a clean up between the tests. However, if you don't know what you're looking for, not having the clean up can lead to confusing and frustrating debugging.

I don't know if I'm too happy with having a dedicated .sql file that I'll run before every test. For two reasons:

  1. I'm hiding information in a .sql file - if I add a new table in my db schema, I'll have to remember to modify the .sql file as well
  2. Chances are that I'll wire the corresponding repositories in my test anyways. At least if I want to set up test data before running my tests. So why not simply call repo.deleteAll()?

Mostly it's a matter of style. If you're working a lot with SQL anyways (and you're proficient with it) I don't see any big issues here. If you're more the person to drive everything through your OR-Mapper, it might be easier to just @Autowire the correct repositories and go with it.

wbiller commented 6 years ago

The thing with the single SQL file is just a personal preference of mine, and yes I always forget to add new tables to the file :D .