Unit Testing: Logging and Dependency Injection

后端 未结 9 565
臣服心动
臣服心动 2021-02-02 14:57

So regards logging from SO and other sites on the Internet the best response seems to be:

void DoSomething() {
    Logger.Log(\"Doing something!\");
    // Code.         


        
相关标签:
9条回答
  • 2021-02-02 15:59

    I'd say it's probably a reasonable thing to write a Unit Test for logging; I've done so before, and it turned out to be more useful than I initially anticipated. Generally, Unit Testing logging gives you good assurance that the logging facility is working at Unit Test time, which can be a nice assurance. I don't find it critical to Unit Test logging, but if you have the inclination, I doubt that it'll be a bad thing, either.

    0 讨论(0)
  • 2021-02-02 16:00

    Personally, I practice TDD/BDD pretty religiously and I almost never test logging. With some exceptions logging is either a developer convenience or a usability factor, not part of the method's core specification. It also tends to have a MUCH higher rate of change than the actual semantics of the method, so you wind up breaking tests just because you added some more informational logging.

    It's probably worthwhile to have some tests that simply exercise the logging subsystem, but for most apps I wouldn't test that each class uses the log in a particular way.

    0 讨论(0)
  • 2021-02-02 16:00

    I would divide the logging into three categories:

    1) A requirement. Some systems require logging for audit purposes, or to fill some other requirement of the project (such as a logging standard in an app server). Then it is indeed a requirement and deserves unit tests and acceptance tests to the point where you can be confident the requirement is met. So in this case the exact string of the log may be tested for.

    2) Problem solving. In case you start getting weird state in QA or production, you want to be able to trace what is going on. In general, I would say that if this is important (say in a heavily threaded application where state can get complicated but can't be reproduced via known steps) then testing that the given state values end up logged can be valuable (so you aren't testing the whole readability of the log, just that certain facts get in there). Even if the class is changed later, that state is still likely to be logged (along with additional state) so the coupling between the test and the logging is reasonable. So in this case, only parts of the logging is tested for (a contains test).

    3) A development aid. In many cases I use logging as a more robust form of commenting. You can write a statement like:

     logger.debug("Extract the fifth instance of BLAH from the string " + s);
    

    So that you can document the code and at the same time have a useful artifact if you do ever need to debug what is going on. In that case I would not unit test at all, as the existence or not of a given statement is not important on its own.

    As for the view that you have to test 100% of everything, see Kent Beck's answer here. I think that the "test everything" is good advice for beginners, because when you start with TDD, the temptation will be to not test anything that is hard to test, or that pushes you to think about the design to make it testable, and rationalize it as unimportant. But once you do know what you are doing, and appreciate the value of the tests, then it is important to balance out what you are doing with what is worth testing.

    0 讨论(0)
提交回复
热议问题