Lalit Mishra
Lalit Mishra

Reputation: 167

How to verify that a superclass' constructor is being called

Let's say there is a super-class

class SuperClass {
    SuperClass(Foo foo) {
        this.foo = foo;
    }

    SuperClass() {
        this.foo = new DefaultFoo();
    }
}

And there's a sub-class

class SubClass extends SuperClass {
     SubClass(Foo foo) {
        super(foo);
    }
}

The class under test is SubClass. I want to verify that SubClass' constructor is indeed invoking it's superclass' non-empty constructor. Is there any way to achieve this?

Upvotes: 1

Views: 3687

Answers (4)

Konstantin Pribluda
Konstantin Pribluda

Reputation: 12367

This should be possible with jmockit ( http://jmockit.googlecode.com ) by mocking superclass. Here is example

( from: https://groups.google.com/forum/?fromgroups=#!topic/jmockit-users/O-w9VJm4xOc )

public class TestClassUnderTest { 

     public class ClassUnderTest extends BaseClassForClassUnderTest 
     { 
        public ClassUnderTest(ISomeInterface si) 
        { 
           super(si); 
         } 
         //... 
      } 
@Test 
public void testSuperConstructorCall() 
{ 
    final ISomeInterface si = new ISomeInterface() 
    { 
    }; 

    Mockit.setUpMock(BaseClassForClassUnderTest.class, new Object() { 
        @Mock 
        public void $init(ISomeInterface si_param) 
        { 
            assertNotNull(si_param); 
            assertTrue(si_param == si); 
        } 
    }); 

    ClassUnderTest cut = new ClassUnderTest(si); 
} 

}

Upvotes: 1

Victor Mukherjee
Victor Mukherjee

Reputation: 11035

You can put a boolean field in your superclass and set it "true" within the non-empty constructor, and thus making it "true" when the non-empty constructor is called. Check the status of that boolean instance field for the corresponding object to know which constructor has been invoked.

Upvotes: -1

Costi Ciudatu
Costi Ciudatu

Reputation: 38205

In order to check that from a unit test, you can simply create a Foo instance, pass it to the SubClass constructor and then check whether instance.getFoo() returns the exact same reference.

Upvotes: 1

Brian Agnew
Brian Agnew

Reputation: 272307

I would test this via the super constructors side effects. e.g. does it set particular fields or change behaviour ?

Note that the implementation of your class should really be shielded from the tests. So you're only interested in how it affects the constructed entity. Otherwise if/when you refactor your class hierarchy you'd have to change your tests, whereas you need them to remain the same in order to perform a regression.

Upvotes: 3

Related Questions