667514 members! Sign up to stay informed.

Sponsored Links


Resources

Enterprise Java
Research Library

Get Java white papers, product information, case studies and webcasts

News News News Messages: 37 Messages: 37 Messages: 37 Printer friendly Printer friendly Printer friendly Post reply Post reply Post reply XML XML XML

Article: Design to Unit Test

Posted by: Joseph Ottinger on November 28, 2007 DIGG
"Design to Unit Test," by Akshay Sharma, walks through a set of requirements to help developers design for unit testing, including some tips for the design stage.
Thinking about unit testing during design leads to a good design. Unit tests are not just pieces to catch ‘bugs’, they also drive the design. Unit tests enforce the contract of the classes and methods and thus making sure the design adheres to the contract of the system. Some of the advantages of thinking of unit testing during design are following:
  • Unit tests drive the developers to think about interfaces. This practice leads to writing loosely coupled code. It also benefits in writing good apis.
  • Unit tests lead to better design by allowing a right mix of composition and interfaces
  • Unit tests drive the need for good method documentation. Remember the standard: If your program isn’t worth documenting, it probably isn’t worth running (Nagler, 1995)

Threaded replies

·  Article: Design to Unit Test by Joseph Ottinger on Wed Nov 28 13:13:54 EST 2007
  ·  documentation by Ric Wang on Wed Nov 28 15:27:45 EST 2007
    ·  Re: documentation by Cedric Beust on Wed Nov 28 15:34:18 EST 2007
      ·  Re: documentation by Ric Wang on Wed Nov 28 15:55:28 EST 2007
      ·  Re: documentation by greg matthews on Wed Nov 28 16:11:52 EST 2007
        ·  Re: documentation by Ric Wang on Wed Nov 28 16:34:37 EST 2007
          ·  Re: documentation by Akshay Sharma on Wed Nov 28 19:13:17 EST 2007
            ·  Re: documentation by Paul Beckford on Fri Nov 30 07:32:33 EST 2007
            ·  Re: documentation by Paul Beckford on Fri Nov 30 08:09:16 EST 2007
      ·  Re: documentation by Dmitriy Setrakyan on Thu Nov 29 01:54:28 EST 2007
    ·  Re: documentation by Mikael Berglund on Thu Nov 29 04:18:16 EST 2007
    ·  Zongying Cao by ZongYin Cao on Wed Feb 20 21:35:49 EST 2008
  ·  Re: Article: Design to Unit Test by Mark Woyna on Wed Nov 28 16:50:20 EST 2007
    ·  Re: Article: Design to Unit Test by Ric Wang on Wed Nov 28 17:20:21 EST 2007
      ·  Re: Article: Design to Unit Test by Mark Woyna on Thu Nov 29 10:58:16 EST 2007
        ·  Re: Article: Design to Unit Test by Ric Wang on Fri Nov 30 15:15:34 EST 2007
    ·  A perfect solution by ZongYin Cao on Fri Feb 22 22:26:00 EST 2008
  ·  Madness! by Hani Suleiman on Wed Nov 28 18:36:36 EST 2007
    ·  Re: Madness! by Ric Wang on Thu Nov 29 12:30:33 EST 2007
      ·  Re: Madness! by Akshay Sharma on Thu Nov 29 12:48:10 EST 2007
      ·  Re: Madness! by Dave Rooney on Thu Nov 29 12:55:36 EST 2007
        ·  use your turn signal a$$holes by Jesse Kuhnert on Thu Nov 29 14:06:09 EST 2007
  ·  YAGNI by Larry Singer on Thu Nov 29 01:21:19 EST 2007
    ·  Re: YAGNI by Thai Dang Vu on Fri Nov 30 15:48:17 EST 2007
      ·  Re: YAGNI by Larry Singer on Sun Dec 02 22:42:43 EST 2007
        ·  Re: YAGNI by Ric Wang on Sun Dec 02 23:25:22 EST 2007
          ·  Re: YAGNI by Larry Singer on Mon Dec 03 21:53:59 EST 2007
            ·  Re: YAGNI by Ric Wang on Tue Dec 04 12:07:30 EST 2007
  ·  Comments and XP by Dave Rooney on Thu Nov 29 12:49:52 EST 2007
    ·  Re: Comments and XP by Cedric Beust on Thu Nov 29 13:53:53 EST 2007
      ·  Re: Comments and XP by Dave Rooney on Thu Nov 29 16:09:55 EST 2007
      ·  Re: Comments and XP by Nikita Ivanov on Thu Nov 29 18:27:27 EST 2007
        ·  Re: Comments and XP by Vikas Hazrati on Fri Nov 30 01:00:27 EST 2007
  ·  Final Conclusions by Leif Ashley on Fri Nov 30 09:50:58 EST 2007
    ·  Re: Final Conclusions by Ric Wang on Fri Nov 30 15:31:38 EST 2007
    ·  Re: Final Conclusions by Rogerio Liesenfeld on Fri Nov 30 18:45:26 EST 2007
  ·  And what about team work by Mordred QV on Fri Feb 01 07:15:09 EST 2008
  ·  Re: Article: Design to Unit Test by Loana Morgane on Sun Apr 06 07:56:26 EDT 2008
  Message #243066 Post reply Post reply Post reply Go to top Go to top Go to top

documentation

Posted by: Ric Wang on November 28, 2007 in response to Message #243027
....
  • Unit tests drive the need for good method documentation. Remember the standard: If your program isn’t worth documenting, it probably isn’t worth running (Nagler, 1995)


  • Does "documentation" mean the same thing as "comments in code"? If so, I guess an Agile developer would say quite different things about this: comments should be kept at a minimal level - your code should be simple and clear enough to speak for itself; comments lie (if not updated properly, and they are often not), but code doesn't.

      Message #243067 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Cedric Beust on November 28, 2007 in response to Message #243066


    Does "documentation" mean the same thing as "comments in code"? If so, I guess an Agile developer would say quite different things about this: comments should be kept at a minimal level - your code should be simple and clear enough to speak for itself; comments lie (if not updated properly, and they are often not), but code doesn't.

    And people wonder why Agile is staying marginal :-)

    There are so many things that are wrong with these statements...

    Starting with the assumption that there is such a thing as universally beautiful code that speaks for itself and does not require comments. I don't care how beautiful you think your code is, because 1) I will probably disagree and 2) I want you to be able to explain what it does in plain English.

    Adding comments to my code has actually very often caused me to refactor it because I realized that it was overly complicated, tried to do too many things or didn't cover all cases.

    Most of the places I have worked at have always required comments accompanying every single check-in, and I would be highly suspicious of any organization that discourages such practice.

    --
    Cedric
    Author "Next Generation Testing in Java"

      Message #243068 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Ric Wang on November 28, 2007 in response to Message #243067

    And people wonder why Agile is staying marginal :-)
    There are so many things that are wrong with these statements...

    Starting with the assumption that there is such a thing as universally beautiful code that speaks for itself and does not require comments. I don't care how beautiful you think your code is, because 1) I will probably disagree


    Not sure about "beautiful", but clear and simple can have some degree of measurements. For example, if "you disagree", that probably means "my code" is NOT simple and clear enough.

    and 2) I want you to be able to explain what it does in plain English.



    Well, that is a whole different requirement. The hope of "test driven" is probably by looking at the code and the Unit Test of it, one would figure out what the code does in plain English (assuming one is an English speaker, that is :).


    Adding comments to my code has actually very often caused me to refactor it because I realized that it was overly complicated, tried to do too many things or didn't cover all cases.


    That is a good point. And there are other things that can trigger refactor, finding the code is difficult to Unit Test for example.


    Most of the places I have worked at have always required comments accompanying every single check-in, and I would be highly suspicious of any organization that discourages such practice.


    Comment when checking in is a good practice. Not sure that's what the author meant here by "documentation", though.

    Author "Next Generation Testing in Java"


    Will try to read your book. Hani is the co-author, right? Love his blog. :)

      Message #243069 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: greg matthews on November 28, 2007 in response to Message #243067


    Does "documentation" mean the same thing as "comments in code"? If so, I guess an Agile developer would say quite different things about this: comments should be kept at a minimal level - your code should be simple and clear enough to speak for itself; comments lie (if not updated properly, and they are often not), but code doesn't.

    And people wonder why Agile is staying marginal :-)

    There are so many things that are wrong with these statements...



    +1

    I guess while we'd all like our code to speak for itself, and that's the target we're trying to hit, it is sensible to be a bit pragmatic and use comments.

    The insight about writing comments helping you identify confusing code, and being a trigger for doing a refactor is something I've also encountered.

    Quite frequently I'll try to comment some code, find that I can't explain it 'nicely' and then refactor it before trying to comment it again.

      Message #243070 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Ric Wang on November 28, 2007 in response to Message #243069
    I guess while we'd all like our code to speak for itself, and that's the target we're trying to hit, it is sensible to be a bit pragmatic and use comments.


    Agreed. And "no comments" is a bit too XP compared to "minimal comment".

    Hey, maybe that's why the author says "unit test drives good method documentation", and leaves the interpretation of "good documentation" to the readers, without getting himself into all the trouble - slick move :)

      Message #243071 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Article: Design to Unit Test

    Posted by: Mark Woyna on November 28, 2007 in response to Message #243027
    Another variation on Option 2 is to isolate all dependencies in protected methods, and then extend the class under test, overriding the methods that have external dependencies with local mock implementations.

    For example,

    public class A {
    private B b;
    public A(B aB) {
    b = aB; // dependency injection
    }

    public void someMethod() {
    if ( b.isValid() ) { doSomething(); }

    protected void doSomething() {...}
    }

    In this example, class A has a dependency on class B. First, we refactor the class to isolate all dependent code:

    public void someMethod() {
    if ( isBValid() ) { doSomething(); }
    }

    protected isBValid() { return b.isValid(); }


    Next, we derive a test class from class A, overloading the methods with external dependencies.

    public class ATest extends A {

    protected isBValid() { return true; }
    }

    Now we can use the test class in our unit tests:

    public class ATest extends TestCase {

    public void test1() {
    A aA = new ATest();
    a.someMethod();
    ...
    }
    }

    I typically define the test classes, and unit test classes as static inner classes of the base class, as this keeps the test implementation close to the actual code. The biggest advantage of this approach is that it leads to much more readable code. The body of the "core" methods do not have *any* external dependencies. They are almost entirely business logic. The extracted methods are basically getter methods.

    Mark

      Message #243072 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Article: Design to Unit Test

    Posted by: Ric Wang on November 28, 2007 in response to Message #243071
    Another variation on Option 2 is to isolate all dependencies in protected methods, and then extend the class under test, overriding the methods that have external dependencies with local mock implementations.
    ....


    Very interesting approach! First time I heard about it. But I can see a couple inconveniences:

    1. If A uses 20 methods on its dependency B, you'd have 20 protected methods on A, as well? Sort of too expensive, no?

    2. It's hard to do "test first/driven" if the test is an inner class of the code :)

      Message #243075 Post reply Post reply Post reply Go to top Go to top Go to top

    Madness!

    Posted by: Hani Suleiman on November 28, 2007 in response to Message #243027
    It is pretty much clinically insane to even think that unit tests are any substitute for documentation.

    Unit tests, if they really are indeed unit tests, do just what they say they do, test units. While this might help you figure out the details of how a particular unit works, its an abysmal way of figuring out how real applications work.

    If your application is so trivial that all it needs are unit tests, then you're fine. In the real world, apps are far more complex and nasty than that, which is why we all have jobs. In that same crazy world, documentation in the form of diagrams, comments, and high level overviews absolutely matters.

    Just look at any open source project of significant size, and see how many contributors managed to contribute significantly just by looking at tests and no other documentation.

      Message #243077 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Akshay Sharma on November 28, 2007 in response to Message #243070
    Nice to see some comments :)

    I would like to stress on one point about this article. It focusses on applications that write (or try to) unit tests at a point after the design and the code has been created. A lot many organizations do that still. Now the guiding light for these applications is the documentation. I have not yet found a good reason to NOT write good documentation for the methods. Imagine writing a unit test for a class that you have (worst case another developer has) written. While agile purists will make a hue and cry about this, sadly this is the way it is a lot of times :(.

    By documentation I mean, method level documentation and sometimes even the implementation comments. Writing documentation brings out any of the hidden or unexposed aspect of a method. I find a lot of advantages in doing so:
    1) It does specify the contract of the method. I hate to see the contract of a method to layout itself by reading the code. The truth is, code over a period of time (multiple release changes by different developers) gets cluttered.
    2) Helps in refactoring (Cedric and Greg have already pointed it out).
    3) It could probably be the only way to understand the features after many updates. I have seen with each release or update, the design is never up to date.
    XP and other agile methodologies might have addressed many of the pain points, but I still think as long as we have new (inexperienced) developers working on older code, we can end up with smelling code. This is where a standard or a process might ease things out.

    I agree the documentation has to be judicious and not just bloat up the class. This would be an onus on the developer, but worthwhile investing.

      Message #243080 Post reply Post reply Post reply Go to top Go to top Go to top

    YAGNI

    Posted by: Larry Singer on November 29, 2007 in response to Message #243027
    Program to an interface not an implementation

    This is an anti-pattern that needs to go the same way as the singleton.

    Go on, ask yourself why you are writing that interface. If the answer is, so that you can test it, then you are wasting your time.

    There are many good reasons for writing interfaces, but making code testable is not one of those reasons. None of the test frameworks require interfaces. The mocking frameworks also do not require interfaces. Thanks to cglib Java classes can be easily decorated to do all that stuff.

    So when you go to create your interface consider if you really need it, because in many cases YAGNI. If you need it later, just do an extract interface refactoring in your favourite IDE.

      Message #243081 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Dmitriy Setrakyan on November 29, 2007 in response to Message #243067
    I don't care how beautiful you think your code is, because 1) I will probably disagree and 2) I want you to be able to explain what it does in plain English.
    I could not agree more. I often find myself looking at code "that speaks for itself" and then having to spend another 20 or 30 minutes trying to understand why it "speaks" in the language I don't understand ;-)

    The truth is that when writing code, the author makes certain assumptions to himself that may not be clear to others. They may not even be clear to the author when he/she looks at the same code after 2 or 3 weeks. That's why adding useful comments is important.

    Usually, when in doubt - better comment it.

    Best,
    Dmitriy Setrakyan
    GridGain - Grid Computing Made Simple

      Message #243083 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Mikael Berglund on November 29, 2007 in response to Message #243066
    Does "documentation" mean the same thing as "comments in code"? If so, I guess an Agile developer would say quite different things about this: comments should be kept at a minimal level - your code should be simple and clear enough to speak for itself; comments lie (if not updated properly, and they are often not), but code doesn't.

    My opinion is that if a developer is unable to update the comments as he is performing changes to the codebase than he is unfit to be a developer. There is no natural law like gravity that forces people to destroy the codebase just because they are making changes.

    I'm also advocating the use of commenting each class with the business case it solves. Like "This class generates price quotes based on weather; good weather gives higher quotes and bad weather lower quotes" if that is a customer requirement. When the customer finds a bug related to weather quotes (i.e. climate change has changed the weather) the developer has to find where this is calculated. Solid comments will help software maintenance and forces the developers to learn the business domain.

      Message #243087 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Article: Design to Unit Test

    Posted by: Mark Woyna on November 29, 2007 in response to Message #243072
    Another variation on Option 2 is to isolate all dependencies in protected methods, and then extend the class under test, overriding the methods that have external dependencies with local mock implementations.
    ....


    Very interesting approach! First time I heard about it. But I can see a couple inconveniences:

    1. If A uses 20 methods on its dependency B, you'd have 20 protected methods on A, as well? Sort of too expensive, no?

    2. It's hard to do "test first/driven" if the test is an inner class of the code :)



    1a) Short answer: Yes, you'd have to overload 20 methods.

    1b) Long answer: I'd consider a design that involved 20 calls between 2 classes a smell. Why does A have such a tight coupling to B? Is it possible to move some of the functionality to B, and reduce the number of calls? Can the calls to B be consolidated in fewer methods? For example, if B is nothing but a DTO-like object, and A is calling a collection of getter methods, then it's probably best to group the calls together in a factory-like method.

    Keep in mind that this approach is just another option. There are certainly times when having a full-blown mock implementation makes sense, especially if other classes are going to use the mock. However, if class A needs to call only 1 method on a class B that exposes 30 methods, I really hate to have to provide a B mock that is required to implement the full B interface, even if the other 29 methods are empty.

    Also, if I need B to behave in certain ways for certain inputs, e.g. throw an exception when a specific parameter value is passed, it's easier to control in my local mock implementation, than to encapsulate it in the shared mock, since I might affect other users of the mock.

    2) Technically, you're correct. :-) However, you can always create an empty class (i.e. no constructor, and no methods) with the test class within it. I'm certainly a big advocate of TDD, but I wouldn't flag you for a violation of the rules.

    One of the advantages of using an inner TestCase class is that it has access to all protected and private methods of the class, without having to make everything public, which is typically what happens when the test class exists in another package. Now, there are those who believe that unit tests should only access public methods, given that all protected and private methods will be exercised by the public methods. I'm in the other camp. I like to build my logic up by utilizing well-tested protected and private methods. It makes debugging easier. If a unit test fails when calling a public method, the defect may be buried in one of the helper methods. By having unit tests for the helper methods, I'm fairly confident that the bug lies in the body of the public method, since the helper methods' tests have all passed.

    Mark

      Message #243091 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Madness!

    Posted by: Ric Wang on November 29, 2007 in response to Message #243075
    Good to see Hani's post, always brightens up the day....

    Anyway back to the topic, although no MD myself to tell anything clinically, I guess anytime you use words like "any", you stick your neck out too much (and I've used it twice in one sentence :) Another point is the scope of the author's is "method" level rather than "application".

    It may be a matter of to which end we should strive at when coding - replying more on the code/test to convey the intent, or document, or both? Certainly one is not the substitute of the other. And it may also depend on the intended audience: Is it a lib kind of code (ex open source lib) intended for the audience to use rather than work on, or is it for biz logic that changes very often.

      Message #243093 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Madness!

    Posted by: Akshay Sharma on November 29, 2007 in response to Message #243091
    Ric, that is an excellent point that you have brought up. Yes, this article's intent for documentation was wholly on the method (and to certain extent class level rather than at a higher or abstract level as application. "I" think that as part of writing unit tests we can say that documentation at method level makes more sense. There is no doubt that we need to supply an abstract view of the same at an application/lib level for the users.

      Message #243094 Post reply Post reply Post reply Go to top Go to top Go to top

    Comments and XP

    Posted by: Dave Rooney on November 29, 2007 in response to Message #243027
    Some comments about, um, comments:

    Adding comments to my code has actually very often caused me to refactor it because I realized that it was overly complicated, tried to do too many things or didn't cover all cases.
    Paraphrasing Martin Fowler, if you feel the need to add a comment, figure out instead how to refactor the code (naming, structure, etc.) such that the comment is no longer required. Having said that, there are always going to be situations where a comment may be helpful. Nowhere does it say that comments are verboten. All that is said is that in many cases you can avoid them through more expressive code.

    Most of the places I have worked at have always required comments accompanying every single check-in, and I would be highly suspicious of any organization that discourages such practice.
    That's a very good practice, and something I do all the time. It's not the same, though, as commenting code.

    Quite frequently I'll try to comment some code, find that I can't explain it 'nicely' and then refactor it before trying to comment it again.
    Sure, I do that as well. Adding the comment helps me think through the problem, then I refactor the code to make the comment unnecessary. What works even better for me is to write a test first! ;)

    Agreed. And "no comments" is a bit too XP compared to "minimal comment".
    Sorry to sound defensive, but please point to all places where it is said that there should be no comments (or documentation for that matter) in XP. I'll make sure that I send a message to the people posting that in order to correct them. XP says to avoid the use of comments, relying instead on more expressive code. How you achieve that is up to you, and two people in this thread already have said that they use comments to help them with that process.

    Usually, when in doubt - better comment it.
    This is OK, but if you feel that the code can be more expressive, make it so! Refactoring is everyone's responsibility, and code ownership is an anti-pattern.

    Dave Rooney
    Mayford Technologies

      Message #243095 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Madness!

    Posted by: Dave Rooney on November 29, 2007 in response to Message #243091
    It may be a matter of to which end we should strive at when coding - replying more on the code/test to convey the intent, or document, or both?
    I believe the answer is 'both'. It also depends on the product for which you're writing code. If it's a business application, you may be able to sway towards the testing side, whereas if you're working on a 3rd party open source library to be used by other developers then you'll need much more documentation inside and outside of the code.

    Dave Rooney
    Mayford Technologies

      Message #243098 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Comments and XP

    Posted by: Cedric Beust on November 29, 2007 in response to Message #243094
    Paraphrasing Martin Fowler, if you feel the need to add a comment, figure out instead how to refactor the code (naming, structure, etc.) such that the comment is no longer required.

    I would love to ask Martin's coworkers how they feel about that...

    The overall idea is truly ridiculous. Here is how it goes:

    "I need to write a comment for these 20 lines of code because the algorithm they implement is a bit tricky"

    "Don't, just extract methods out of these 20 lines. See now, you have four methods scattered in your class and zero comments, isn't it much cleaner?"

    <blink>

    It's healthy to always wonder if you couldn't refactor your code further, but the urge to write a comment should be encouraged and not be frowned upon.

    Ideally, you will want to have these comments reviewed, just like your code, which will give you the best of both worlds: clean code and clean comments that go with it.

    Anyway, like Hani and I say multiple times in our book, we are just fans of common sense and open enemies of one-liners that are supposed to dictate how you write your code.

    --
    Cedric
    Author "Next Generation Testing in Java"

      Message #243101 Post reply Post reply Post reply Go to top Go to top Go to top

    use your turn signal a$$holes

    Posted by: Jesse Kuhnert on November 29, 2007 in response to Message #243095
    That's what not commenting your code feels like for other developers having to look at your API - whether internal or public facing.

    It's like using your turn signal when driving - you don't have to of course, but everyone else is going to think you're an a$$hole when you don't. I shouldn't have to look at source code to understand an API no matter where it is written....such b.s. esp. these days when IDEs make it so easy/automated. no excuse.

    I believe the answer is 'both'. It also depends on the product for which you're writing code. If it's a business application, you may be able to sway towards the testing side, whereas if you're working on a 3rd party open source library to be used by other developers then you'll need much more documentation inside and outside of the code.

    Dave Rooney
    Mayford Technologies


      Message #243112 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Comments and XP

    Posted by: Dave Rooney on November 29, 2007 in response to Message #243098
    "I need to write a comment for these 20 lines of code because the algorithm they implement is a bit tricky"
    Twenty lines is rather long for one method... I would be looking to split it into multiple methods anyway.
    It's healthy to always wonder if you couldn't refactor your code further, but the urge to write a comment should be encouraged and not be frowned upon.
    As always, Cedric, it depends on the situation. For example if you're implementing a financial algorithm and want to provide a reference for it's source, it makes perfect sense to add a comment since code alone won't convey that information. Again, if you're writing an API for other developers, you absolutely require documentation in the code.

    However, if a class, method or variable name isn't expressive it should be changed so that it is. I prefer to err on the side of verbosity when naming, and I believe that it helps with readability.
    Anyway, like Hani and I say multiple times in our book, we are just fans of common sense and open enemies of one-liners that are supposed to dictate how you write your code.
    Agreed wholeheartedly. We just differ on the delivery method.

    Dave Rooney
    Mayford Technologies

      Message #243118 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Comments and XP

    Posted by: Nikita Ivanov on November 29, 2007 in response to Message #243098
    Anyway, like Hani and I say multiple times in our book, we are just fans of common sense and open enemies of one-liners that are supposed to dictate how you write your code.

    Could not agree more... Common sense and good judgmental frame of reference are one of the most important tools a software developer can have. Agile development is often "described" as a laundry list of specific techniques and rules while it was introduced precisely to advance common sense approach and move away from monolithic and put-in-stone methodologies of 80s and 90s.

    Blind preference to refactoring over comments is just idiotic in my opinion.

    My 2 cents,
    Nikita Ivanov.
    GridGain - Grid Computing Made Simple

      Message #243129 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Comments and XP

    Posted by: Vikas Hazrati on November 30, 2007 in response to Message #243118

    Blind preference to refactoring over comments is just idiotic in my opinion.


    In my view refactoring should always be the first choice. If you feel that after refactoring the code is not readable enough and there is only so much refactoring that you can do, then add comments to make the functionality clear.

    More often that not, whatever we say, I have seen code being updated and the outdated comments still remaining there.

      Message #243131 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Paul Beckford on November 30, 2007 in response to Message #243077
    I would like to stress on one point about this article. It focusses on applications that write (or try to) unit tests at a point after the design and the code has been created.


    I think this is the point. As always there is more than one way to skin a cat. If you define the tests (and the behavior) before you write the code then it is a whole new ball game :^)

    In this scenario, your tests aren't really tests, because there is no code to test at this point. Instead they are a design specification for the code "to be". Sounds weird I know, but it is much the same as a method comment written before you write the actual method itself :^).

    I think for test first development, then tests are indeed a design specification, hence the rise in popularity of BDD (behavior driven design) with the associated removal of testing language to emphasize this fact.

    Take a look at rpsec:

    http://rspec.rubyforge.org/

    Rbehave does a similar thing for Java.


    Now is this always sufficient? well in a lot of cases no. Higher level documentation may be needed. But is it better then comments at the top of a method? Well I think so, because the design contract specified in tests can be verified through execution. Were as comments cannot be verified at all. The comment can say one thing and the code may do something very different.

    Paul.

      Message #243133 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: documentation

    Posted by: Paul Beckford on November 30, 2007 in response to Message #243077
    I would like to stress on one point about this article. It focusses on applications that write (or try to) unit tests at a point after the design and the code has been created.


    I think this is the point. As always there is more than one way to skin a cat. If you define the tests (and the behavior) before you write the code then it is a whole new ball game :^)

    In this scenario, your tests aren't really tests, because there is no code to test at this point. Instead they are a design specification for the code "to be". Sounds weird I know, but it is much the same as a method comment written before you write the actual method itself :^).

    I think for test first development, then tests are indeed a design specification, hence the rise in popularity of BDD (behavior driven design) with the associated change in language to emphasize the fact.

    Take a look at rpsec:

    http://rspec.rubyforge.org/

    Rbehave does a similar thing for Java.


    Now is this always sufficient? well in a lot of cases no. Higher level documentation may be needed. But is it better then comments at the top of a method? Well I think so, because the design contract specified in tests can be verified through execution. Were as comments cannot be verified at all. The comment can say one thing and the code may do something very different.

    Paul.

      Message #243137 Post reply Post reply Post reply Go to top Go to top Go to top

    Final Conclusions

    Posted by: Leif Ashley on November 30, 2007 in response to Message #243027
    Ok I just had to say something at the end of this very long thread.

    First off, the rule of thumb for testing code should be, "do whatever it takes to test code and build reliable applications". Meaning if you need interfaces or server changes were you normally wouldn't, then you do it. This idea that interfaces and other features should be used for business logic and not testing is just short sighted... the entire exception framework in Java is literally for testing running code. Use the tools.

    Well over 50% of application design is testing and debugging (my average is about 60%). The best way to improve your prototype to production times is to reduce testing and debugging. Period.

    Also, EasyMock and jMock, the two most pervasive mocking frameworks, use interfaces. So I'm not sure what mocking framework you guys are using.

    Last on documentation, which isn't what this was about in the first place, Fowler is right. If the code needs explanation, then it probably needs refactoring. But what does "explanation" mean? It means if you have to document the steps of an application because the coding is unclear, then that's explanation. It does NOT mean you should skip javadoc or adding comments inline to document a specific codeblock because changes were made to meet business needs.

    However the only time there should be inline documentation (and I mean ONLY), is to document those anomalies where the code must be structured a certain way or for choices made because of issues like dependencies external to that section. If the code needs even light step-by-step documentation, then that's what a design document is for, not code.

    I actually met a guy once that was big on AOP and wanted inline code doc. How do you preach separation of concerns while at the same time you want to put your design document inside the code base? Think about it...

      Message #243163 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Article: Design to Unit Test

    Posted by: Ric Wang on November 30, 2007 in response to Message #243087

    ...
    1b) Long answer: I'd consider a design that involved 20 calls between 2 classes a smell. Why does A have such a tight coupling to B? Is it possible to move some of the functionality to B, and reduce the number of calls? Can the calls to B be consolidated in fewer methods? For example, if B is nothing but a DTO-like object, and A is calling a collection of getter methods, then it's probably best to group the calls together in a factory-like method.
    ...
    Mark


    Could you elaborate a bit on that cos I have some situations like that. The factory-like method is on A or B?

    One specific scenario is that B auto-generated from an XML schema by Jaxb/Castor; now wanting to add some "behaviors" to it, A is used to decorate B. Obviously being an object representative of an XSD, B has tons of getters/setters. How would you go about this?

    Thanks.

      Message #243165 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Final Conclusions

    Posted by: Ric Wang on November 30, 2007 in response to Message #243137
    Not sure there is such thing as "final" :)

    First I was not clear the author is not talking about Test Drive at all until he clarified it. And that makes a lot of the discussions here out of context.

    But for the interface topic, JMock supports mocking of concrete classes by using cglib. The gotcha, however, is that the class being mocked has to be a JavaBeans, or at least have a protected no-arg constructor such that cglib can do the runtime subclass trick.

    I think there are situations where interfaces are YAGNI, but those are not often. And the "interface is YAGNI" statement is not generally true.

    As for the "refactor vs comment, which one to strive for first", I am in the camp of refactor first and fall back to comment when further refactor hurts the readability rather than helps.

      Message #243167 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: YAGNI

    Posted by: Thai Dang Vu on November 30, 2007 in response to Message #243080
    There are many good reasons for writing interfaces, but making code testable is not one of those reasons. None of the test frameworks require interfaces. The mocking frameworks also do not require interfaces. Thanks to cglib Java classes can be easily decorated to do all that stuff.
    Maybe I don't understand what you said or I use interfaces for the testing reason wrong.

    class B implements IB {
    ...
    }

    class A {
    private IB iB; // dependency injection
    void methodIWantToTest() {
    iB...
    ...
    }
    }

    I want to test that method in A, but I haven't written B yet. So I write MockB (implementing IB) which is injected to A. Then I can test that method. So, is my testing approach wrong? or is there anything better?

    Regards.

      Message #243184 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Final Conclusions

    Posted by: Rogerio Liesenfeld on November 30, 2007 in response to Message #243137
    Also, EasyMock and jMock, the two most pervasive mocking frameworks, use interfaces. So I'm not sure what mocking framework you guys are using.

    Well, you can always use JMockit :)


    Rogério

      Message #243219 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: YAGNI

    Posted by: Larry Singer on December 02, 2007 in response to Message #243167
    class B implements IB {
    ...
    }
    ...
    So I write MockB (implementing IB) which is injected to A.

    In your example you have introduced the interface IB solely so that you can create a mock implementation of that interface. There appears to be no other reason for this interface.

    Instead you could use a framework such as JMock which allows you to mock an object directly. Initially write B with empty implementations and let JMock check you are calling the methods correctly.

    Then write the unit tests for B and finally the implementation of B itself.

      Message #243220 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: YAGNI

    Posted by: Ric Wang on December 02, 2007 in response to Message #243219
    ...
    Instead you could use a framework such as JMock which allows you to mock an object directly. Initially write B with empty implementations and let JMock check you are calling the methods correctly.
    Then write the unit tests for B and finally the implementation of B itself.


    This would work initially. But that limits B to be a JavaBean or at least having a protected no-arg constructor. As soon as B stops being that way, JMock will stop working because cglib only works within those limits. That's unnecessary limitation on B. So an interface still makes sense here.

      Message #243299 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: YAGNI

    Posted by: Larry Singer on December 03, 2007 in response to Message #243220
    You are correct that JMock requires a no-arg constructor, however this is not a limitation of cglib itself. You actually have a choice here:

    • provide a protected no-arg constructor

    • create the interface

    • use a different test tool or hack JMock


    Each of these choices are valid in certain circumstances. For me this is still not enough reason to create an interface.

      Message #243328 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: YAGNI

    Posted by: Ric Wang on December 04, 2007 in response to Message #243299
    You are correct that JMock requires a no-arg constructor, however this is not a limitation of cglib itself. You actually have a choice here:

    • provide a protected no-arg constructor



    So you don't consider that YAGNI - providing a constructor just so JMock would work?

  • create the interface


  • I prefer this over unnecessary constructor.

  • use a different test tool or hack JMock



  • That's too much labor just to avoid an interface, which is a couple clicks in an IDE, no?

    Each of these choices are valid in certain circumstances.


    Agreed. But we are talking about the one case as in the code put out here.

    For me this is still not enough reason to create an interface.


      Message #246736 Post reply Post reply Post reply Go to top Go to top Go to top

    And what about team work

    Posted by: Mordred QV on February 01, 2008 in response to Message #243027
    Most is very logical and self-explanatory what's being written in that document, at least, it is to me. But all these theories don't solve the practical dilemma of different testing mentalities. It's all fine when everybody in the team points with their nose in the same direction, but it's far more difficult to practise *any* kind of good test code if you are one of the few writing tests (properly). In the end, the chain is as strong as it's weakest link.

    I practise testing for years now, learned TDD from in the beginning and try to apply it if I have the choice, and yes, the results have been wonderful so far, design insight has improved, bug frequence decreased, blabla, so conclusion: the theory DOES match the reality. But I still haven't figured out how you make good testing principles shared among members of your team that have totally opposite views on testing and design.

    I once read an interview about this with Alberto Savoia : (http://theserversidecom.bitpipe.com/detail/RES/1181322440_580.html?src=wc_atssc_sitepost_06_14_07_c&li=58958)

    And yes, it made a lot of sense to me, don't be dogmatic, let ppl choose their own approach but still keep some core principles in mind etc. Well, that's very nice in theory, but in practice you still have to be lucky that those core principles get respected properly. I'm still pretty convinced that you can't change the mentality of every individual. And my experience so far tells me that once you are talking about good design/testing principles, a lot of people immediately turn their head once they realise that this frightning "oh my god" characteristic pops up : discipline.

    Also, and quite relevant to, I'm really wondering how many ppl can make comparisons between the mentalities on those topics but in different technologies. Once you have a group of ppl where the views don't match, try to make testing (or design principles for that matter) work. Yes yes I know the scope of the GOF patterns , but I'm not so sure if that means they are interpreted in the same way.

    My guess is that a lot doesn't depend on what is good and what is bad. But rather on how well one can persuade other people to believe in something. There is no such thing as "the truth of testing", there are many truth's out there, and none of them are entirely true.

    This could be a point where I could become philosophical, but that doesn't feed my test coverage does it.

      Message #247756 Post reply Post reply Post reply Go to top Go to top Go to top

    Zongying Cao

    Posted by: ZongYin Cao on February 20, 2008 in response to Message #243066
    The good code should describe itself clearly or it should be refactored.

      Message #247857 Post reply Post reply Post reply Go to top Go to top Go to top

    A perfect solution

    Posted by: ZongYin Cao on February 22, 2008 in response to Message #243071
    Another variation on Option 2 is to isolate all dependencies in protected methods, and then extend the class under test, overriding the methods that have external dependencies with local mock implementations

    ....

    Mark


    This is a practical solution for the code of which the bad and un-testable design can't be improved in a short time. It's a perfect temporary solution.

      Message #250085 Post reply Post reply Post reply Go to top Go to top Go to top

    Re: Article: Design to Unit Test

    Posted by: Loana Morgane on April 06, 2008 in response to Message #243027
    In fact, when you write code, precaution to be taken is simply to leave it at the disposal of the contributors and rework later. I use this system to my blog rencontre

    New content on TheServerSide.comNew content on TheServerSide.comNew content on TheServerSide.com

    Dependency Injection in Java EE 6 - Part 1

    Reza Rahman explores the features of the proposed JSR 299, Contexts and Dependency Injection for Java EE (CDI). When approved, it promises to be a key feature of Java EE 6. (November 2, Article)

    SAML: It's Not just for Web services

    SAML is an XML-based standard for exchanging authentication and authorization data between security domains. The single most important problem that SAML was created to solve is the Web browser Single Sign-On problem. Many organizations are debating whether to stay with version 1.1 or move to 2.0. This article makes observations about both options. (September 28, Article)

    Programming is Also Teaching Your Team

    Joe Ottinger takes a look at how people learn, and applies it to the practice of programming. He notes that understanding how people learn is an essential part of working in a programming team. (September 22, Article)

    Can Java EE Deliver The Asynchronous Web?

    Stephen Maryka gave us an article about the Asynchronous Web and posed a number of questions that get examined like an approach to delivering Asynchronous Web capabilities through extensions to existing Java EE technologies. (July 14, Article)

    JSF Flex

    JavaServer Faces Flex goal is to provide users capability in creating standard Flex components, part of flexSDK which is open sourced through MPL license, as normal JSF components. This article by Ji Hoon Kim will provide an overview of creating a simple multilingual JSF page consisting of JSF Flex tags. (June 29, Article)

    The Rules of SOA - A Road to a Successful SOA Implementation

    In this session Jeff explores the key characteristics of successful SOA projects. He covers some of the patterns, and anti-patterns, tool sets, and strategies that he himself learned the hard way. Last, he provides a strategy and blueprint for achieving a high likelihood of success in your SOA project. (June 23, Tech Talk)

    Ari Zilka Talks About Terracotta 3.1

    Ari Zilka, CTO of Terracotta, Inc., talks about the new features in Terracotta 3.1, announced during JavaOne and available now. (June 15, Tech Talk)

    Enterprise Application Integration, and Spring

    In this Tech Talk, Josh Long explores an integration challenge using Spring Integration and walks through the implementation, employing and expanding on the basic patterns of Enterprise Application Integration to tie together components into a function integration solution, and then demonstrates how Spring Integration helps address the integration requirements. (June 15, Tech Talk)

    Google Web Toolkit: An Introduction

    In this Tech Talk, David Geary teaches you: The basics of Google Web Toolkit; How to implement Ajax-enabled applications in Java; Internationalization; Hooking into the browser history mechanism; Remote procedure calls. (June 4, Tech Talk)

    Just Enough Early Architecture to Guide Development

    Jon Kern discusses the best architecture/technical solutions and ensure that they are repeated by all developers. By tackling the architecture up-front in a serial manner, subsequent parallel development will be much more manageable and predictable. (May 28, Tech Talk)

    Productive Programmer: On the Lam from the Furniture Police

    This keynote describes the frustrations of modern knowledge workers in their quest to actually get some work done, and solutions for how to guard yourself against all those distractions. Neal Ford talks about environments, coding, acceleration, automation, and avoiding repetition as ways to defeat the misguided attempts to sap your ability to produce good work. (May 26, Tech Talk)

    Auto-Scaling Your Existing Web Application

    Gil demonstrates how new, aggressive uses of already abundant compute capacity by common applications offer competitive value for application designers. (May 21, Tech Talk)

    Automating Hibernate Mapping and Queries For Java Web Development

    Chris Keene introduces WaveMaker as a new way to automate the ability to generate Hibernate classes in order to more quickly bring OR mapping into an application. (May 19, Article)

    Auto-Scaling Your Existing Web Application

    In this session Nati Shalom demonstrates how to take a standard Java EE web application and scale it out or down dynamically without changes to the application code. Seeing as most web applications are over-provisioned to meet infrequent peak loads, this is a dramatic change because it enables growing your application as needed, when needed, without paying for unutilized resources. (May 19, Tech Talk)

    Free Book PDF Download: Mastering EJB Third Edition

    Mastering EJB was one of the original and most influential EJB books in the industry. Mastering EJB III now returns with two new expert co-authors, updated for EJB 2.1 and 30% new chapters including security, integration, best practices, open source, and more.
    (Book PDF Download)

    Application Server Matrix

    The Application Server Matrix is a detailed listing of J2EE vendors and their application server products, with information on latest version numbers, J2EE spec support and licensing, pricing, platform support, and links to product downloads and reviews.
    (Application Server Comparison Matrix)

    News | Blogs | Discussions | Tech talks | Patterns | Reviews | White Papers | Downloads | Articles | Media kit | About
    Java Solutions
    All Content Copyright ©2007 TheServerSide Privacy Policy
    Site Map