Is it possible to test a local value using a junit test?
Sometimes I would like to test an intermediate value in a metho开发者_运维技巧d. But the method can't be split. So I wonder if JUnit can only test a method as a unit. If I can put something like a breakpoint in a method, and get the local value and assert it, it will be better. If it is impossible, how do you solve this kind of problem.
Adding a break point is not really unit testing and in fact not testing at all. You can call it checking but there is no such thing as Check Driven Development.
Anyhow, people new to Unit testing quite often find this issue that they want to test private or local values let that be a variable or method. When I started TDD I was in fact quite phased by it myself. But the thing is, in Unit testing the purpose is to do black box testing of a particular functionality and all possible outcomes from that. What happens inside that black box is not your concern nor do you need to unit test it.
If you feel like testing an intermediate value then maybe your method is too long and should be split into two or more testable small methods. And if it can not be done then you should not be worrying about testing them.
If that intermediate value is getting its value from another public method then it's that method that you want to test in separate unit test, not the value inside the method you are currently testing.
Your question leads to an explanation of the D's in TDD. Particularly when you use TDD to mean "Test-Driven Design" (although some people prefer the phrase "Test-Driven Development").
As @Shahzeb points out, maybe your method is too long and should be split into two methods, with one of them producing the intermediate value and the other one taking it as input. Our inclination to think about code this way is quite literally Driven by the tests. The Design of our code is better, because we are separating concerns in the interest of begin able to test them. So you're asking a good question (whose short and simple answer is "No"), and these are the kinds of questions that permit TDD to improve our design.
The idea is that you don't test the private (intermediate) value at all because it's not externally important (which is why you're wisely keeping it private.) The private value represents some state in your object that you set now with the intent that it will affect future calls to your public interface, right? So change your one test to make two calls. Have the first call do whatever it needs to set the state the way you think it should be, then make a second call, and see that it resulted the way you expect when that variable is set. If it's truly private, it doesn't matter to the unit test what its value is - only that it correctly produces the desired results at the right time. But this suggestion comes with a warning: it's creeping into that turf where you may be asking a unit test to do more than a unit's worth of testing.
Another observation: you say your method "can't be split" but don't offer an explanation why. If you can't change the design, it sounds more like you're possibly trying to wedge a unit test into legacy code, as opposed to performing Test Driven Development. That's perfectly OK, you don't have to give up on TDD here, but perhaps there are other approaches to consider. Once you're passing the test, in TDD this is the part where you would refactor the method a bit. The fact that you're talking about an intermediate value suggests that your method has too much responsibility. Consider using extract method to encapsulate more concise parts of the functionality into smaller, testable service methods.
If that's not what you're trying to accomplish, it's possible the testing you're trying to perform is thinking "too big". Maybe the testing you're trying to do is more of an acceptance test. Again, that's fine, and acceptance tests are very important too, but it isn't really a unit test anymore.
精彩评论