From: King D. <Ki...@tc...> - 2002-01-30 21:37:39
|
I have a situation where when I construct an object I pass an object to the constructor that the constructor will call a method on with itself as a parameter. This is part of a SAX parser and the object being constructed is a ContentHandler. The object being passed to the constructor is the XMLReader that the object being constructed is to register itself with. The constructor looks like this: public BaseContentHandler( XMLReader reader ) { this.parentHandler = reader.getContentHandler(); this.reader = reader; reader.setContentHandler( this ); } You can see this pattern in the XML parsing code in the Ant project (which is where I got the idea). Whether this is a good pattern is debatable, but either way it should be testable. I created a MockXMLReader object to verify that the constructed object is setting itself as the content handler. The setContentHandler method calls setActual on an ExpectationValue. The problem is that I cannot set the expected value until the constructor returns because I don't have an object reference until the constructor returns. But the setExpected call does a clearActual which clears the actual value just set within the constructor. So I have a problem of which comes first the chicken or the egg or in this case the expected or the actual. The question is how to solve it and should Mock Objects be changed to make this easier? I could subclass ExpectationValue and override clearActual so that clearActual does nothing, but that is not robust and makes the object not reusable. I cannot realistically override setHasExpectations which is the one that is actually calling clearActual because that is the only way to set the myHasExpectations variable which is private to AbstractExpectation. One way is to create a wrapper for the expected value to provide an additional level of indirection. It would look like this (I haven't even tried to compile this) public class ExpectationWrapper { private Object expected; public void setExpected( Object expected ) { this.expected = expected; } boolean equals( Object actual ) { // Should use equals method with check for null // but you get the idea. return expected == actual; } } Then my test case would look like: MockXMLReader reader = new MockXMLReader(); ExpectationWrapper wrap = new ExpectationWrapper(); reader.setExpectedContentHandler( wrap ); wrap.setExpected( new BaseContentHandler( reader ) ); reader.verify(); This strikes me as very kludgey and it seems I should not have to go to such lengths just because I want to set the actual before the expected. I understand that usually you want to clear the actual when you set the expected, but sometimes you don't. The question boils down to is there any reason why the expected must be set before the actual? Any thoughts? -- Dale King |