spockframework/spock — pull request #36 by marcingrzejszczak (2014-02-14 13:27:36+00:00)
Title: InjectMocks - Property, Setter, Constructor injection

1) We stick to creating mocks in the standard Spock way
2) The objects (not only mocks) that should be injected will be annotated with @Collaborator
3) The object that should have the dependencies injected into will be called @Subject
4) The injection takes place as in Mockito (http://docs.mockito.googlecode.com/hg/latest/org/mockito/InjectMocks.html)

>Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.

>Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only.
Note: If arguments can not be found, then null is passed. If non-mockable types are wanted, then constructor injection won't happen. In these cases, you will have to satisfy dependencies yourself.

>Property setter injection; mocks will first be resolved by type, then, if there is several property of the same type, by the match of the property name and the mock name.
Note 1: If you have properties with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won't happen.

>Note 2: If @InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.

>Field injection; mocks will first be resolved by type, then, if there is several property of the same type, by the match of the field name and the mock name.
Note 1: If you have fields with the same type (or same erasure), it's better to name all @Mock annotated fields with the matching fields, otherwise Mockito might get confused and injection won't happen.

>Note 2: If @InjectMocks instance wasn't initialized before and have a no-arg constructor, then it will be initialized with this constructor.

5) At least one element is annotated with Collaborator - we inject only those elements
6) There is no element annotated with Collaborator - all properties are considered for injections