Skip to content

Support constructor parameters for spying on abstract classes #685

@mockitoguy

Description

@mockitoguy

Nice, 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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions