com.atlassian.jira.mock.component
Class MockComponentWorker

java.lang.Object
  extended by com.atlassian.jira.mock.component.MockComponentWorker
All Implemented Interfaces:
ComponentAccessor.Worker

public class MockComponentWorker
extends Object
implements ComponentAccessor.Worker

This component worker can be used with the ComponentAccessor to return mock instances of components for unit testing.

When a class needs to access another JIRA component, the preferred mechanism to resolve this dependency is by injection in the constructor. Among other things, this makes it easier to see what the dependencies of the class are and also makes it easy for unit tests to provide mocks for those components. However, there are times when dependency injection is impossible or impractical. Examples include:

In these cases, the class can use ComponentAccessor.getComponentOfType(Class) to resolve the dependency, instead. The drawback is that ComponentAccessor uses a global, static reference to a ComponentAccessor.Worker implementation to accomplish this, and if nothing has initialised that reference, then an IllegalStateException is thrown.

Unit tests must be responsible for ensuring that everything they require, directly or indirectly, is arranged during the test's setup, so a unit test that encounters this problem should explicitly initialise the component accessor. In most cases, all they need to do is create and install an instance of this class. For example:

     @Before
     public void setUp()
     {
         new MockComponentWorker().init();
     }
 

The MockComponentWorker comes with a few mocks by default, including implementations for common problem areas, such as the UserKeyService and the UserPreferencesManager, so for many tests this will be enough as-is. If you need additional mocked components to be resolved in this way, then you can add them as well. An example might look something like this:

     @Before
     public void setUp()
     {
         final ApplicationUser fred = new MockApplicationUser("Fred");
         final JiraAuthenticationContext jiraAuthenticationContext = Mockito.mock(JiraAuthenticationContext.class);
         Mockito.when(jiraAuthenticationContext.getUser()).thenReturn(fred);
         Mockito.when(jiraAuthenticationContext.getLoggedInUser()).thenReturn(fred.getDirectoryUser());
         new MockComponentWorker()
                 .addMock(ConstantsManager.class, new MockStatusConstantsManager())
                 .addMock(JiraAuthenticationContext.class, jiraAuthenticationContext)
                 .init();
     }
 

JUnit 4 annotations can also be used to initialise the MockComponentWorker. See the MockComponentContainer and MockitoContainer @Rules for examples.

Since:
v4.4

Constructor Summary
MockComponentWorker()
           
 
Method Summary
<T,U extends T>
MockComponentWorker
addMock(Class<T> componentInterface, U componentMock)
          Registers a mock component to be returned by this component worker.
<T> T
getComponent(Class<T> componentClass)
          Obtains the registered mock of the specified interface type.
<T> T
getComponentOfType(Class<T> componentClass)
          Although the ComponentAccessor specifies different semantics for this method, in this mock implementation it behaves identically to getComponent(Class).
 MockApplicationProperties getMockApplicationProperties()
           
 MockUserKeyStore getMockUserKeyStore()
           
 MockUserPreferencesManager getMockUserPreferences()
           
<T> T
getOSGiComponentInstanceOfType(Class<T> componentClass)
          Although the ComponentAccessor specifies different semantics for this method, in this mock implementation it behaves identically to getComponent(Class).
 UserKeyServiceImpl getUserKeyService()
           
 MockComponentWorker init()
          Convenience method that just calls ComponentAccessor.initialiseWorker(this).
<T,U extends T>
void
registerMock(Class<T> componentInterface, U componentMock)
          Registers a mock component to be returned by this component worker.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

MockComponentWorker

public MockComponentWorker()
Method Detail

registerMock

public <T,U extends T> void registerMock(Class<T> componentInterface,
                                         U componentMock)
Registers a mock component to be returned by this component worker.

Since addMock(Class, Object) is identical but also returns this for call chaining, it may be more convenient to use.

Type Parameters:
T - the componentInterface
U - the componentMock's class, which must implement <T>
Parameters:
componentInterface - the interface that the mock component must implement
componentMock - the component that implements the interface
See Also:
addMock(Class, Object)

addMock

public <T,U extends T> MockComponentWorker addMock(Class<T> componentInterface,
                                                   U componentMock)
Registers a mock component to be returned by this component worker.

This method is exactly equivalent to registerMock(Class, Object), except that it also returns this, making it possible to use it in the convenient call chaining style illustrated in the documentation for this class.

Type Parameters:
T - the componentInterface
U - the componentMock's class, which must implement <T>
Parameters:
componentInterface - the interface that the mock component must implement
componentMock - the component that implements the interface
Returns:
this, for convenience

getComponent

public <T> T getComponent(Class<T> componentClass)
Obtains the registered mock of the specified interface type. Test code would normally only need to call this to retrieve access to mocks that were provided automatically (such as the UserKeyService) or that the test registered earlier and is now ready to stub.

JIRA itself will also sometimes use this method (or getComponentOfType(Class)) to resolve dependencies. Arguably, this method should throw an exception rather than return null when a component is requested without a mock provided for it; however, some unit tests will resolve the component during construction without the test code path actually needing to use it, so this method just generates a warning message in the log for this case.

Specified by:
getComponent in interface ComponentAccessor.Worker
Type Parameters:
T - the return type inferred from the specified componentClass.
Parameters:
componentClass - the interface for which an implementation is desired
Returns:
the requested component, or null if no mock implementation has been provided for it.

getComponentOfType

public <T> T getComponentOfType(Class<T> componentClass)
Although the ComponentAccessor specifies different semantics for this method, in this mock implementation it behaves identically to getComponent(Class).

Specified by:
getComponentOfType in interface ComponentAccessor.Worker
Type Parameters:
T - as for getComponent(Class)
Parameters:
componentClass - as for getComponent(Class)
Returns:
as for getComponent(Class)

getOSGiComponentInstanceOfType

public <T> T getOSGiComponentInstanceOfType(Class<T> componentClass)
Although the ComponentAccessor specifies different semantics for this method, in this mock implementation it behaves identically to getComponent(Class).

Specified by:
getOSGiComponentInstanceOfType in interface ComponentAccessor.Worker
Type Parameters:
T - as for getComponent(Class)
Parameters:
componentClass - as for getComponent(Class)
Returns:
as for getComponent(Class)

init

public MockComponentWorker init()
Convenience method that just calls ComponentAccessor.initialiseWorker(this). If you are developing a plugin that must support JIRA versions prior to v6.0, then that @Internal method must be used directly, instead.

Since:
v6.0

getMockUserKeyStore

public MockUserKeyStore getMockUserKeyStore()

getMockUserPreferences

public MockUserPreferencesManager getMockUserPreferences()

getMockApplicationProperties

public MockApplicationProperties getMockApplicationProperties()

getUserKeyService

public UserKeyServiceImpl getUserKeyService()


Copyright © 2002-2014 Atlassian. All Rights Reserved.