Reputation: 6003
So I have three classes: A, B, C. I need to write unit tests for class A
.
class A extends B{
//fields go here ...
public A(String string, ...){
super.(string,...);
}
//other methods here ...
}
class B{
C stuff;
//other stuff
}
So C
is an important resource (like JDBC or ssh Session). Naturally, I am mocking C
. How do I mock B
. Imagine B
has many children classes that extends it.
My main problem is that A
is calling super.(...)
. I don't want to inject methods into A
just for testing. To me that's bad design. Any ideas how to mock the parent?
For example I cannot do class MockB extends B{...}
and then try MockB obj = new A();
This would not work because both MockB
and A
would be children of B
.
Upvotes: 4
Views: 12864
Reputation: 41137
You really shouldn't try to mock the superclass of the class under test. While some mocking frameworks allow "partial mocks" that might make it possible to partially mock the class you're actually testing, it's a bad idea.
If class A
and the relation between A
and B
are sufficiently complex that you think you need this, they should probably not be in an inheritance relation at all.
Consider changing your code so that B
delegates to A
instead of extending it.
Upvotes: 11
Reputation: 14550
you want to mock B class which means you are probably not testing B nor A. so why do you care if it calls super, foo, bar or other methods? do you know how many methods jdbc calls? but as you said, you have no problem with mocking it. same here. you just do
B mockOfB = Mockito.mock(B.class);
that's it. you have a mock of B and you can test any invocations you like.
if you are testing A so why you can't simply instantiate it? does constructor of B require some static dependencies? in this case you should refactor it or use something like powermock (if you really can't refactor the class). if you can't instantiate B because it is abstract then just extend it in your test
Upvotes: 3