Definitely. Some people say "any test is better than no test at all". I strongly disagree - badly written tests bog down your development time, and you end up wasting days fixing "broken" tests because they weren't good unit tests in the first place. For me at the moment, the two things I'm focusing on to make my tests valuable, rather than a burden, are:
Maintainability
You should be testing the outcome (what happens), not the method (how it happens). Your set-up for the test should be as decoupled from the implementation as possible: only set up results for service calls etc that are absolutely necessary.
- Use a mocking framework to ensure your tests don't depend on anything external
- Favour stubs over mocks (if your framework distinguishes between them) wherever possible
- No logic in tests! Ifs, switches, for-eaches, cases, try-catches etc. are all big no-nos, as they can introduce bugs into the test code itself
Readability
It's okay to allow a bit more repetition in your tests, which you wouldn't normally allow in your production code, if it makes them more readable. Just balance this out with the maintainability stuff above. Be explicit in what the test is doing!
- Try to maintain an "arrange, act, assert" style for your tests. This separates out your set up and expectations of the scenario, from the action being performed, and the result being asserted.
- Maintain one logical assertion per test (if the name of your test has "and" in it, you may need to break it down into multiple tests)
In conclusion, you should be very concerned with "smelly" tests - they can end up just a waste of your time, providing no value.
You've said:
Unit testing usually requires various "smelly hacks" like stubbing functions.
Sounds like you could definitely do with reading up on some Unit Testing techniques, such as using a Mocking framework, to make your life a heck of a lot easier. I'd very very strongly recommend The Art of Unit Testing, which covers the above and much much more. I found it enlightening after struggling with poorly-written, unmaintainable, "smelly" tests for a long time. It's one of the best time investments I've made this year!