Unit testing strategies for a layered Java Rest application -


i puzzled regarding right way should unit tests. let's have write junit tests basic java rest crud application composed of these "common layers" each layer calls sub layer:

  • controller layer (ex: accountrestcontroller.getaccount(id) - returns json of account)
  • service layer: (ex: accountservive.getaccount(id) - returns account object )
  • repository layer (ex: accountrepository.getaccount(id) - returns account object )
  • domain layer (ex: account (id, name) )
  • database table (ex : account(id, name) )

we have following hypothesis (or restrictions) unit tests (not sure appropriate though ?)

  • they have out of container (no tomcat\jetty , no in memory database - guess in integration test)
  • use mocking (for example mockito framework)

so questions are:

  • what best way\the right way\the best practices write unit tests type of application ?
  • to rigorous, have unit test each layer(controller, service, repository, domain) independently mocking each time sub layer
  • would unit testing top rest controller enough?
  • ... , again ... hypothesis appropriate ? (couldn’t unit testing container & in memory database?)

regards

and jump right opinionated waters...

i start writing tests bottom layer, , go up, letting upper layers call real thing under (as long it's contained within code and/or easy predict correct behaviour of lower layer). while more integration test, works me.

for me crucial part "unit testing" not have correct unit tests per these definitions, have automated test can run fast enough (usually keep them under 3s in c++ including compilation, in android+java have huge performance problems, whole ide+toolchain insanely slow, leading times 5+ seconds, on larger projects hitting 20-30s gradle build, , i'm trying run basic unit tests, far away in c++, tests closer qa set).

and if fail, should easy pinpoint cause of failure. call layers deep inside, failure in base class leads many failures, have problem identify cause within quick look, not worrying me.

when files/databases gets involved, things slower, tend differentiate "unit test" , belongs integration/qa set. still in-memory db can quite ok basic things.

i prefer these bastard tests, because when mock layers under/above code being tested, makes me worried "bake" expected result test much, missing bugs when mock wrong. plus mocking additional work, when run time of tests low price pay, gladly turn "integration" tests.

in android/java have seen/used:

  • i mockito lot, somehow fits way think mocking nicely.
  • robolectric (android specific) heavy weight, use sparsely, feels better fit mocking pretty everything.
  • dagger , other dependency injection libs: can't these, clash way write unit tests, , don't see benefit of using them, prefer write dependency injection in pure java, it's same number of lines in source, , source expect when reading after few years.
  • bus/event libraries: these annoy me much, didn't yet figure way how test event driven code thoroughly , easily, tests feels way staged , full of assumptions, plus these hard mock.

btw, if possible, unit test while developing (close tdd approach). doing unit tests afterwards more painful, api quite set (already used other parts/project), , when realise it's difficult test easily, it's late already, or big refactoring next (without tests covering original version, error prone).

for java rest crud app sounds me of api can tested trough layers without performance penalty (with db mocked/injected/in-memory, , other external systems solved in similar way). i'm doing in java android stuff, don't have direct experience such scenario.


Comments