问题
I would like to know if I can mock a super class constructors call and its super() calls.
For example, I have the following classes
class A
{
A(..)
{
super(..)
}
}
class B extends A
{
B(C c)
{
super(c)
}
}
So, I am planning to unit test some methods in class B, but when creating an instance it does call the super class constructors making it tough to write unit tests. So, how can I mock all the super class constructor calls. Also I would like to mock few methods in class A so that it does return few values as I need.
Thanks!!
回答1:
You could use PowerMock library. It is really a lifesaver when you need to accomplish things like yours. https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior
回答2:
Mocking a constructor is a very bad idea. Doing so is circumventing behavior that will happen in production. This is why doing work in the constructor, such as starting threads and invoking external dependencies, is a design flaw.
Can you honestly say that the work performed in the constructor has no effect on the behavior you're trying to test? If the answer is no, you run the risk of writing a test that will pass in a test environment, but fail in production. If the answer is yes, that is a plain case for moving that "work" outside the constructor. Another alternative is to move the behavior you're trying to test to another class (maybe it's own).
This is even more true if you're using a DI framework like Guice (which I assume because you tagged it that way).
回答3:
The short answer to your question is "not exactly." You can't 'mock' a constructor, let alone a super. Also mocking super.anyMethod is difficult or impossible with mocking frameworks I'm familiar with. Powermock does allow you to suppress super constructors and problematic methods, which isn't quite the same as mocking them, but could help.
When B extends A, it is of course completely coupled with A. That's not a problem per se but it can be and it looks like it is here. Instead of having B extend A, try having B contain an A instead (and perhaps implement the same interface if necessary). Then you can inject a mock A and delegate all of the calls that you want. That would be much easier to unit test, no?
It's one of the benefits of test driven development that you discover these things in your design during testing.
来源:https://stackoverflow.com/questions/10421357/mock-a-superclass-constructor