Keyboard Shortcuts
Likes
Search
Please critique this TDD flow
I have a domain entity called a "Booking Window" that has a Start Date and End Date, and defines a period in which a Member can make a Booking.? The business is a mobile car wash, and Members can book a wash every 14 days.
I have a means of establishing the first Booking Window - at the point of the Member signing up.? Now I feel like the next most useful function is one that finds all Booking Windows closing "today" and makes new ones. So I wrote a test like this (kinda pseudo coded) test("nothing to do when no booking windows at all", async () => { ? ? const client = stubGraphQlClientContainingNothing() ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(0) }) export async function makeTodaysBookingWindows(client: GraphQlClient, clock: Clock): Promise<BookingWindow[]> { ? ? return [] ? } test("nothing to do when no booking windows end today", async () => { ? ? const client = stubGraphQlClientContaining(bookingWindowEnding(tomorrow())) ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(0) ? }) test("create a new booking window when one expires today", async () => { ? ? const client = stubGraphQlClientContaining(bookingWindowEnding(today())) ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(1) ? ? expect(window[0].startDate).toBe(today()) ? ? expect(window[0].endDate).toBe(today() + 14 days) ? }) test("create a new booking window for every window ending today", async () => { ? ? const client = stubGraphQlClientContaining(bookingWindowEnding(today()), bookingWindowEnding(today())) ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(2) ? ? expect(window[0].startDate).toBe(today()) ? ? expect(window[0].endDate).toBe(today() + 14 days) ? ? expect(window[1].startDate).toBe(today()) ? ? expect(window[1].endDate).toBe(today() + 14 days) ? }) |
Hi Mike,
?
my first impression is that you have some interesting logic that is now coupled to your GraphQL engine.? Are you sure you want this?? Since the business logic around your use case might be non-trivial, then implementing it all in GraphQL could be non-trivial and the resulting code might by hard to change.? It's all fair if the logic is very stable and you need every drop of performance.? An alternative way would be to query GraphQL for the minimal set of data that your logic needs to make a decision, and then implement the interesting business logic in a separate function, that is pure and synchronous.
?
I also question whether you really want a single function that does querying, business logic, and saving an updated state on the DB.? Perhaps you would be better served by 3 separate functions.
?
Hope this?helps a bit,
?
Matteo |
On Thu, Jul 7, 2022 at 10:16 AM Matteo Vaccari <matteo.vaccari@...> wrote: Hi Mike, I have a similar impression. You will probably notice, if you continue this way, that you will eventually be duplicating a lot of silly details about GraphQL in your tests, even though the code you write ends up being mostly plain JavaScript to make the new tests pass. At some point, you might decide that this feels wrong somehow and it would help you to isolate the plain JavaScript behavior from the GraphQL parts. This would make the tests simpler and execute more quickly, which improves your feedback loop and helps you change the "core business" behavior more easily.
Again, I agree that this will probably eventually happen. The same advice applies: if you continue by putting everything in one place, then eventually you'll notice that some of your tests have copy/paste duplication of distracting details, and if you separate these three bits of behavior into separate pieces, then the distracting details go away and the remaining details feel much more relevant and meaningful. I interpret this as a good sign, generally. Good luck. J. B. (Joe) Rainsberger :: ?:: :: -- J. B. (Joe) Rainsberger :: :: :: Teaching evolutionary design and TDD since 2002 |