4 ms·
I call those lockdown tests and they're a smell. You don't want to dictate the implementation, just the inputs and outputs. The former leads to very brittle cod
by grogenaut 4y ago
I call those lockdown tests and they're a smell. You don't want to dictate the implementation, just the inputs and outputs. The former leads to very brittle code, the latter describes and validates the contract. It's also important where you put the logic of the test in the code base when you have multiple layers. This latter part is harder and system dependent.
In many cases mocks are now over used where previously they were important in say 2008. Especially now with languages that support functions as objects, better generics, and other features which weren't common a while back. Likewise frameworks are and languages are generally way more testable now which means you're doing less backflips like static injecting wrappers for DateTime.now into libraries to make tests work. This further allows more contract and less implementation specific testing.
As with most things there is a lot of nuance/art to doing it well and smoothly
- codemonkey-zeta 4y ago> You don't want to dictate the implementation, just the inputs and outputs When programmers really embrace dependency injection like the parent comment, the implementation largely is the inputs, and your code expects them all to be implemented correctly (or mocked correctly by test code). I completely agree that mocks are overused, and their importance in 2008 were in my view a direct result of the popularity of dependency injection patterns. Following that logic, the best way to remove mocks from your tests is to minimize dependency injection, relegating it all to a single place in the code wherever possible, and implementing all other domain logic as pure functions of input to output. How to test that code which touches other systems? Integration tests (or multi-system tests or whatever you like to call them).
- grogenaut 4y agoI generally agree with you, DI went really far in many ways through up to like 2015. In 2008, I actually found code often got more testatable when it was dependency injected. I spent a month ripping singletons out of a gui application so we could make it into a web service, that would have been a lot easier with a DI model. The system was nigh-on untestable until we got rid of those singletons. I link it in another comment but https://github.com/gaffo/CSharpHotChocolateZeroQLIntegrationTestExample https://github.com/gaffo/CSharpHotChocolateZeroQLIntegration... is how I do things these days, api integration test, and more focused unit tests where you don't understand the library well yet, there's lots of tricky edge cases, or error conditions such as setup that are harder to integration test. I'm still feeling it out.