3 ms·
Testing is hard when the code it tests is OOP, has mutations everywhere, and has big functions that do too many things. It's practically impossible to thorough
by z9znz 4y ago
Testing is hard when the code it tests is OOP, has mutations everywhere, and has big functions that do too many things.
It's practically impossible to thoroughly test such code with one assertion per test; it would mean having dozens of tests just for one object method. Correspondingly, the fixtures/factories/setup for tests would balloon in number and complexity as well to be able to setup the exact circumstance being tested.
But the example in TFA is, imo, bad because it is testing two entirely different (and unrelated) layers at once. It is testing that a business logic delete of a thing works correctly, and that a communication level response is correct. Those could be two separate tests, separating the concerns, and resulting in simpler code to reason about and less maintenance effort in the future.
We want to know if the DeleteAsync(address) behaves correctly. Actually we want to know if DeleteReservation() works, irrespective of the async requirement. Testing whether AnythingAsync() works is something that is already done at the library or framework level, and we probably don't need to prove that it works again.
Write a test for DeletReservation() which tests if a valid reservation gets deleted. Write another related test to ensure that a non-existent or invalid reservation does not get deleted, but rather returns some appropriate error value. That's two, probably quite simple tests.
Now somewhere higher up, write the REST API tests. ApiDelete()... a few tests to establish that if an API delete is called, and the business logic function it calls internally returns a successful result, then does the ApiDelete() return an appropriate response? Likewise if the business logic fails, does the delete respond to the API caller correctly?
- drewcoo 4y ago> Testing is hard when the code it tests is OOP, has mutations everywhere, and has big functions that do too many things. Yes, that means the software being tested is not very testable. And should probably be refactored. https://en.wikipedia.org/wiki/Testability https://en.wikipedia.org/wiki/Testability
- commandlinefan 4y ago> when the code it tests is OOP In my experience when code isn’t OOP, that means all static functions with static (I.e. global) data which isn’t hard to test, it’s actually impossible because you can’t mock out the static data.
- z9znz 4y agoI didn't downvote you, but I have a hard time either understanding your meaning or imagining the scenario you describe. Can you give an example? OOP functions are usually harder to test because they expect complete objects as arguments, and that tends to require a lot more mocking or fixtures/factories to setup for the test. FP functions typically operate on less complex and more open data structures. You just construct the minimum thing necessary to satisfy the function, and the test is comparatively simple. None of this has anything to do with global data. Using global data from within any functions is generally a bad idea and has nothing to do with FP or OOP.
- commandlinefan 4y ago> FP functions Pure functional, yeah, absolutely - that’s not what I usually see though. I see procedural/iterative static functions that connect to static data that connect to live databases and immediately start caching its contents locally.