How to apply TDD to a package-by-layer design?

J R

I've been reading quite a lot about TDD, especially about various practices and experiences, dos and don'ts and I'm still puzzled about several aspects after trying to apply it on a Spring Boot application with persistence and REST, all packaged by feature.

Many blog posts and answers here on StackOverflow suggest that we should test the interface and not the implementation. However, examples, like those in "Growing Object-Oriented Software, Guided by Tests" by Steve Freeman and Nat Pryce, suggest quite a different approach, since all of them test implementations mostly, asserting number of method calls, etc. So our tests actually become dependent on the implementation itself. Of course, we can use inversion of control - pass the dependencies via constructors and mock them out in our tests, but is there really a point in mocking, let's say, a CRUD repository?

Maybe I'll give you a simple example to better picture this situation. Let's say we have a multipage user information form, and each form page has to be saved separately.

So, the planned structure of the information package could be like this following package-by-feature approach:

com
.. example
.... user
...... information
........ basic
.......... + BasicInformationDto
.......... + BasicInformationService
.......... - BasicInformationServiceImpl
.......... - BasicInformationDao
.......... - BasicInformationRepository
........ additional
.......... + AdditionalInformationDto
.......... + AdditionalInformationService
.......... - AdditionalInformationServiceImpl
.......... - AdditionalInformationDao
.......... - AdditionalInformationRepository
........ + InformationRestController

+ is public and - is default access modifier

My first idea:

  1. Write a simple REST integration test to test mappings provided by InformationRestController.
  2. Create InformationRestController with those mappings.
  3. Create test for BasicInformationService, create a BasicInformationServiceImpl object, mock BasicInformationRepository and test if repository's save method gets called exactly once.
  4. Create classes for BasicInformationService, BasicInformationServiceImpl and BasicInformationRepository with BasicInformationDao.
  5. Refactor, implement details, dto and dao fields, etc.

What if I later decide to use repository`s #saveAndFlush? Is it normal that a unit test needs to be refactored because of such a small change? And if I test only the interface, how do I test different implementations with different dependencies implementing it?

So how, using TDD, would one design, for example, the BasicInformationService`s save method if it only maps a DTO object to a DAO and then persists it using BasicInformationRepository?

Dave Schweisguth

Briefly, BDD (behavior-driven development), a refinement of TDD, starts with acceptance tests which test the entire stack, then test-drives details with unit tests as necessary. You can unit-test every class if you want, but you don't have to, and I don't where it doesn't add value. In the case you give, I suspect there would be no need to unit-test most of the components.

It is perfectly normal to target a known design when doing TDD/BDD, either because your framework requires it or because that design is already established in other vertical slices of your program. Only the most extreme TDDers start without a framework. What you don't want to do is make up a big design that your framework doesn't require and that testing and refactoring haven't told you yet that you need.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to TDD and Design Recursive function?

How to implement time-distributed dense (TDD) layer in PyTorch

TDD function design in D

Program Design - Package by Feature vs. Layer or Both?

How to apply TimeDistributed layer on a CNN block?

How to apply (call) a single layer on data in Keras?

How to apply a polygon mask layer in ggplot

How to apply regularization only to one layer in pytorch?

how to apply a patch in a debian package?

How to package AWS CDK into Lambda layer?

How to apply TDD if one does not know how the code is supposed to work or be implemented?

How to apply correctly the margins on elements in responsive design?

how to apply a material design to file input tag?

Bower: How to patch a package or apply overrides?

When and how to apply error correction in emmeans package

How to apply layer-wise learning rate in Pytorch?

How to apply l2 normalization to a layer in keras?

How to apply kernel regularization in a custom layer in Keras/TensorFlow?

How to apply opacity to KML layer on top of Google Maps in the React framework?

How to apply the coordinate limits to one layer only in ggplot?

How to (efficiently) apply a channel-wise fully connected layer in TensorFlow

How do I apply custom data augmentation as preprocessing layer in tensorflow?

How to apply a 3x3 filter with a convolutional layer correctly?

How to apply a different dense layer for each timestep in Keras

How to apply different size kernel filters on a single convolutional layer

how to remove a ol-mapbox-style layer loaded with apply method

How to TDD with pandas and pytest?

How to design the label for tensorflow's ctc loss layer

How to design the Embedding Layer in Neural Network in order to have a better quality?

TOP Ranking

  1. 1

    Failed to listen on localhost:8000 (reason: Cannot assign requested address)

  2. 2

    Loopback Error: connect ECONNREFUSED 127.0.0.1:3306 (MAMP)

  3. 3

    How to import an asset in swift using Bundle.main.path() in a react-native native module

  4. 4

    pump.io port in URL

  5. 5

    Compiler error CS0246 (type or namespace not found) on using Ninject in ASP.NET vNext

  6. 6

    BigQuery - concatenate ignoring NULL

  7. 7

    ngClass error (Can't bind ngClass since it isn't a known property of div) in Angular 11.0.3

  8. 8

    ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

  9. 9

    Spring Boot JPA PostgreSQL Web App - Internal Authentication Error

  10. 10

    How to remove the extra space from right in a webview?

  11. 11

    java.lang.NullPointerException: Cannot read the array length because "<local3>" is null

  12. 12

    Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

  13. 13

    flutter: dropdown item programmatically unselect problem

  14. 14

    How to use merge windows unallocated space into Ubuntu using GParted?

  15. 15

    Change dd-mm-yyyy date format of dataframe date column to yyyy-mm-dd

  16. 16

    Nuget add packages gives access denied errors

  17. 17

    Svchost high CPU from Microsoft.BingWeather app errors

  18. 18

    Can't pre-populate phone number and message body in SMS link on iPhones when SMS app is not running in the background

  19. 19

    12.04.3--- Dconf Editor won't show com>canonical>unity option

  20. 20

    Any way to remove trailing whitespace *FOR EDITED* lines in Eclipse [for Java]?

  21. 21

    maven-jaxb2-plugin cannot generate classes due to two declarations cause a collision in ObjectFactory class

HotTag

Archive