Support constructor parameters for spying on abstract classes
See original GitHub issueNice, self-contained enhancement that makes Mockito API more robust. The implementation does not require proficiency with Mockito codebase.
Feature
We already support spying on abstract classes by allowing parameterless constructor. However, there is no support for constructor parameters. This has been asked about long time ago. Mockito API is not robust enough if it supports mocking with constructor but not when one has any constructor parameters.
//current api:
Foo spy = mock(Foo.class, withSettings() .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
//existing method (will remain):
MockSettings useConstructor();
//new api (change existing method):
Foo spy = mock(Foo.class, withSettings() .useConstructor("someArg").defaultAnswer(CALLS_REAL_METHODS));
//changed method:
MockSettings useConstructorArgs(Object ... args);
Open questions
- in case we find multiple matching constructors, do we just use the 1st matching (option 1) or throw an exception (option 2)?
I’d say we go for option 1 because it’s simpler to implement and seems more convenient (works out of the box for certain use cases). If we go for option 2 we need to inform the user what to do to resolve the problem (for example document and suggest @fluentfuture idea of creating an inner implementation)
- do we add new method or add vararg to existing useConstructor() method?
We decided that using existing method is simpler, keeps the API small and is easy to discover.
Implementation notes
- the main complexity is to identify and detect the right constructor to use based on types of parameters supplied by the user
- we already deal with detecting constructors for the @InjectMocks functionality - there should be code to reuse
Test coverage
- see existing tests that cover “useConstructor” method for
- ensure decent, informative exception messages
- if user supplies wrong constructor args (wrong types, we cannot find matching constructor)
- if the constructor throws some exception (constructors of some types have code that can fail)
- when one uses existing parameter-less “useConstructor” method but the mocked class requires constructor args, the exception message should tell the user about new “useConstructorArgs” method.
- what if arguments supplied by the user match more than 1 constructor - either we fail gracefully with decent message or we pick one of the constructors.
- update documentation to describe new feature. Update documentation for existing parameter-less “useConstructor” method. Update documentation in main Mockito class if it references “useConstructor”.
- other use cases?
Issue Analytics
- State:
- Created 7 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
Thank you very much for contribution. It’s really nice work!
I happened to need to dig up the history of @Spy AbstractClass in #106. And I found that all my concerns against constructor-args were already stated in that thread. And it was clear that @szczepiq is fine with the trade-off.
So, while I disagree with the design decision, my apologies for repeating myself over again. 😃