Skip to content

A sample codebase demonstrating how to write efficient and flexible automated tests when using repositories

License

Notifications You must be signed in to change notification settings

Maltcommunity/repository-test-example

Repository files navigation

repository-test-example

A sample codebase accompanying the following article: A guide to safely and efficiently test code that uses repositories.

What does the code do?

A shell application is built to allow users to manage their tasks.

A task is a very simple concept here: it's composed of a summary and a description, and it belongs to an owner. This is enough for our demonstration, and it already allows for imagining several realistic use cases.

Points of interest

  • A repository interface speaking the language of the domain (i.e. a compile-time contract): TaskRepository
  • Automated tests defining the runtime contract that implementations of the above interface must respect: TaskRepositoryContract
  • A (so-called) "Fake" in-memory implementation of the repository contract: InMemoryTaskRepository (and its tests: InMemoryTaskRepositoryTest).
    (Note: a Fake may expose more operations than the contract, for instance here: a clear method.)
  • An implementation of the repository contract using PostgreSQL: PostgresqlTaskRepository (and its tests: PostgresqlTaskRepositoryTest)
  • A way to easily use Testcontainers with Spring: PostgresqlTest
  • The contract tests guarantee that the in-memory repository is as much a valid implementation of the repository as the PostgreSQl one. Those two implementations are interchangeable.
  • Fixtures for easily writing unit tests using of the in-memory implementation of the contract: TaskFixtures, TaskCommandsFixtures
  • No test uses "Mocks", neither manually written nor generated by a library. Instead, tests use the actual implementations of all classes, except that in-memory repositories are used. (But as written earlier, in-memory repositories are fully valid implementations.). See TaskMergeServiceTest, CurrentUserTaskServiceTest or TaskCommandsTest for examples of unit tests making use of it, both in the domain module and in the app module.

While not related to our main demonstration, the code also features:

Why a shell application?

Because:

  1. for this example, it doesn't matter which kind of application is built
  2. we work with Web apps every day :-)

How to run the shell app

Unfortunately the shell doesn't play well with Spring's bootRun task, that's why the app must be built first:

# build the app
./gradle build

# start the DB
docker-compose -f dev-env/docker-compose.yml start

# start the app
java -jar task-shell-app/build/libs/task-shell-app-0.0.1-SNAPSHOT.jar

# play a bit with the app, type "quit" to quit

# stop the DB
docker-compose -f dev-env/docker-compose.yml stop

About

A sample codebase demonstrating how to write efficient and flexible automated tests when using repositories

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published