XpdWiki
Set your name in
UserPreferences Edit this page Referenced by
JSPWiki v2.0.52
![]() ![]() |
Brad Appleton describes LoD as follows: A method "M" of an object "O" should invoke only the the methods of the following kinds of objects:
I guess I am unclear of the statement 'its direct component objects'. Does this mean that a method can aquire a reference to another component? or does a component have to also be passed as a parameter? I would imagine that means objects that belong directly to "O" Lets take a EJB application as an example. This application has classes A, B and C that utilize a bean. Each of the classes have 1 or more methods which call the bean directly. Now the question is how do the methods get a reference to the bean. Here are some scenarios;
Option #1 doesn't violate Demeter but is hard to test. Option #2 doesn't violate Demeter, can not be tested and requires even more code duplication. Option #3 violates Demeter (I think) but is easier to test. Option #4 doesn't violate Demeter and is easy to test but requires extra parameter. Obviously #4 is the best solution. However, is it always practical to pass every collaborating object into the method as a parameter? - GarethReeves OliBye suggests this is what delegation is for. Can you give an example from experience of a situation where it's not possible? I can. Where something is statically initialised in an ancestor class. --SteveF The question is, 'is it always practical?' not 'is it always possible?'. But you have pointed out a case where it isn't possible. What did you do in this case? It was picking up some resource, so we just had to supply it in the file system. :-( Yeah, I have had the same issue. If VAJ would store resources in the repository it wouldn't be much of an issue. Do you structure your code to accept all collaborating objects as parameters? --GarethReeves Either that or instance variables. It's amazing how far you can go. --SteveF How do you set the type of the instance variables? We used factory method on the class until so many of the classes required identical factories that we had to abstract them into a static class --GarethReeves Why do you say that #1 is not testable? Your tests of A, B, C, D can be done by subclassing each of them, and overriding the factory method to return a MockObject instead of the bean. I'm planning of doing this for the case where my class creates an object that is used and disposed of during the course of a single method... I can't pass the object in as a parameter, and the object is not a member variable of the class-under-test. In other cases, I split a method into two parts, where one creates the object (such as file-reference) and the other method takes that object as a parameter. Now the second method can be tested by passing in a MockObject instead of a file-reference. If the first method does only the actions of creating the object and passing it into the second method, then I can say that it unlikely to break and maybe skip testing it. -- KeithRay? Yes, you're right and this is what we have been doing with one difference. Instead of subclassing the class we have a setter for the factory, this lets us set the type of class that the factory creates. Subclassing to test has been something that we have been debating recently, I try and avoid it whenever possible. There are two problems that can occur, a sub class could be overriding more than it should be (this can often happen when two pairs are writting tests for the same class at the same time). It is also sometimes hard to see when a test is initializing a subclass instead of a class. Maybe I am just more used to looking for setters on factories. --GarethReeves Yet one more reason not to use EJB in OliBye's opinion. We use toplink and have a facade which hides toplink (and therefore the database) from our code, but that allows us to unit test that the correct queries are being built. This after all is the only thing we're interested in testing. I know oracle can SQL. Ofcourse we check the queries against oracle in functional tests. Perhaps we should open a debate on InlineVersusExternalTestCode?. -- MarcuS The other danger with subclassing for test classes, as TimM discovered, is that you won't have an override when people add new methods later in the parent. There's something I don't quite get here (which may be to do with retrofitting MockObjects) because these approaches seem to be getting more complicated than I'm used to. Can you post a code fragment and maybe we can try to refactor it? --SteveF There's an interesting question here of what you're testing. If the transient class has a proper test suite, then maybe it's OK to just use it and test the containing class. Depends on the complexity. --SteveF Yes, I like this question. 'Is it ok to bite off larger chunks to test if the additional parts have their own tests?'. Sorry to repeat the question without answering it. --GarethReeves Anyone looked at DemeterSoftware? TellDontAsk
|