[ 
https://issues.apache.org/jira/browse/ACCUMULO-2497?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13941269#comment-13941269
 ] 

Bill Havanki commented on ACCUMULO-2497:
----------------------------------------

A. That would work, except it would require a change to the code under test to 
{{new}} the different class, and then a change back to the "real" one later. In 
contrast, code using a factory can just offer a setter for which factory to 
use: in production a factory for real objects is used, while under test one for 
mocks is used. That way, the same code can be used in test and production, 
untouched.

{code}
// for code example above
void setInstanceFactory(InstanceFactory ifactory) {
  this.ifactory = ifactory;
}
{code}

B. In order for the code to be testable there needs to be hooks for things like 
mocks to be injected ... so-called "design for testability". There's no easy 
way to hook into {{Instance instance = new ActualInstance()}}, because you 
can't override a constructor. A factory field that can be set is an easy hook 
to use. Now, the factory _implementation_ that provides a mock object 
definitely belongs in test code only, but since the factory interface must be 
in the code under test, the interface can't be.

{code}
testedObject.setInstanceFactory(new RealInstanceFactory());  // for reals
testedObject.setInstanceFactory(new TestInstanceFactory(mockInstance));  // for 
test
{code}

The downside is that there is this {{setInstanceFactory}} method that has to at 
least be package-visible, which is why these testability methods are usually 
documented with "only use for testing" or annotated @VisibleForTesting or 
something like that. It can get messy.

> InstanceFactory
> ---------------
>
>                 Key: ACCUMULO-2497
>                 URL: https://issues.apache.org/jira/browse/ACCUMULO-2497
>             Project: Accumulo
>          Issue Type: Improvement
>          Components: client
>            Reporter: Bill Havanki
>            Assignee: Bill Havanki
>            Priority: Minor
>              Labels: factory, static, testability
>             Fix For: 1.6.1, 1.7.0
>
>
> Working on ACCUMULO-2470 (unit tests for server/base) is made difficult by 
> the heavy dependence on static method calls in our architecture. This ticket 
> is for introducing an {{InstanceFactory}} interface that will greatly ease 
> testing of code that currently retrieves instances via static methods (e.g., 
> {{HdfsZooInstance.getInstance()}}).
> Limitations:
> * Work here should be limited to creating {{InstanceFactory}} and its 
> implementations, and not integrating it into existing code (yet).
> * Work is limited to 1.6 and later. To avoid perturbing the 1.6.0 release no 
> new code may be introduced into the public API ({{Instance}} is in the public 
> API).
> * A refactoring of the client API is being considered (see ACCUMULO-2128), so 
> this change should not further complicate - and should hopefully help - that 
> future effort.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to