Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I want to write a class A that has a method calculate(<params>). That method sho

ID: 654899 • Letter: I

Question

I want to write a class A that has a method calculate(<params>). That method should calculate a value using database data. So I wrote a class Test_A for unit testing (TDD). The database access is done using another class which I have mocked with a class, let's call it Accessor_Mockup.

Now, the TDD cycle requires me to add a test that fails and make the simplest changes to A so that the test passes. So I add data to Accessor_Mockup and call A.calculate with appropriate parameters.

But why should A use the accessor class at all? It would be simpler (!) if the class just "knows" the values it could retrieve from the database. For every test I write I could introduce such a new value (or an if-branch or whatever).

But wait ... TDD is more. There is the refactoring part. I could refactor class A using the DB accessor. But I could refactor it in any other way as well (e.g. introducing new classes that encapsulate the data). So, again: How do I write tests that force A to use the database (and nothing else)?

Explanation / Answer

If you just wrote calculate() without requiring it to use the database, it would need to get its data from somewhere else. I know, that sounds trivially simple and boring, but please bear with me. So write that. Let's say that "somewhere else" is most naturally a new parameter or two. Now you can test to your heart's delight without using a real database or mocking one. And now you have a clean, independent, nicely decoupled unit. That's good design. And it's test-driven design. You can call your new method from a class that does have database access, and feed it from the database. But testing that interaction will be less arduous, because you already trust - even know - that the calculate() unit is working correctly. So all the testing you need to do with your database-associated calculation is that it's feeding the right values to your well-tested calculate() method.

That is separation of concerns and that is good design. You started with an assumption about your design: that calculate() would entail both the concern of database access and the concern of calculation. That's a somewhat muddy assumption, a somewhat weak design. And the difficulty you have in testing under that assumption reveals better design. That is TDD.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote