My favorites | Sign in
Project Logo
             
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Copyright (c) 2009 by Alistair A. Israel
*
* This software is made available under the terms of the MIT License.
*
* Created May 29, 2009
*/
package dirty.mockito;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.junit.Before;

import dirty.mockito.junit.rules.ActiveTestRule;

/**
* <p>
* JUnit 4 test parameterized base class that performs instantiation, mocking
* and injection of mocks. Uses an internal {@link ActiveTestRule} to perform
* mocking of elements annotated with <a href=
* "http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mock.html"
* ><code>&#064;Mock</code></a> then inject those mocks into fields (in the
* object under test) annotated with <code>&#064;Autowired</code>.
* </p>
* <p>
* Suppose we have a JPA DAO class, that depends upon an
* <code>&#064;Autowired</code> <code>EntityManager</code>:
* </p>
*
* <pre>
* public class WidgetDao {
* &#064;Autowired
* private EntityManager em;
*
* public Widget find(final Long id) {
* return em.find(Widget.class, id);
* }
* }
* </pre>
* <p>
* Now, to write a unit test for <code>WidgetDao</code> using
* <code>ActiveTest</code>, we simply extend
* <code>ActiveTest&lt;WidgetDao&gt;</code>, declare a field of type
* <code>WidgetDao</code>, declare another field of type
* <code>Entitymanager</code> and annotate that using <code>&#064;Mock</code>.
*
* <pre>
* public class WidgetDaoTest extends ActiveTest&lt;WidgetDao&gt; {
* private WidgetDao widgetDao;
* &#064;Mock
* private EntityManager em;
*
* &#064;Test
* public void testFind() {
* widgetDao.find(123L);
* Mockito.verify(em).find(Entity.class, 123L);
* }
* }
* </pre>
* <p>
* That's it. ActiveTest takes care of creating the mocks for fields annotated
* <code>&#064;Mock</code>, instantiating the class under test (
* <code>WidgetDao</code>), and injecting the mock objects into
* <code>&#064;Autowired</code> fields.
* </p>
* <p>
* Because Spring itself is used to inject <code>&#064;Autowired</code>
* dependencies, <code>ActiveTest</code> supports field, setter and
* constructor-based injection.
* </p>
*
* @param <T>
* the type of the class to instantiate and inject mocks into
* @author Alistair A. Israel
* @see <a href="http://code.google.com/p/dirty-mockito/" target="_blan
* >dirty-mockito</a>
* @see <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans/factory/annotation/Autowired.html"
* target="_blank>&#064;Autowired</a>
* @see <a href=
* "http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mock.html"
* target="_blank>&#064;Mock</a>
* @since 0.1
*/
public class ActiveTest<T> {

/**
* The {@link ActiveTestRule} that does all the mojo.
*/
private final ActiveTestRule<T> activeTestrule;

/**
*
*/
public ActiveTest() {
final Class<T> classUnderTest = determineTypeParameter();
this.activeTestrule = ActiveTestRule.thatWorksOn(classUnderTest);
}

/**
* @return the Type parameter to our generic base class
*/
@SuppressWarnings("unchecked")
private Class<T> determineTypeParameter() {
Class<?> specificClass = this.getClass();
Type genericSuperclass = specificClass.getGenericSuperclass();
while (!(genericSuperclass instanceof ParameterizedType)
&& specificClass != MagicTest.class) {
specificClass = specificClass.getSuperclass();
genericSuperclass = specificClass.getGenericSuperclass();
}
final ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;

final Type firstTypeParameter = parameterizedType
.getActualTypeArguments()[0];
return (Class<T>) firstTypeParameter;
}

/**
* For now, we do it this way. When JUnit >= 4.7.1 comes out, we can fully
* make use of ActiveTestRule as a proper rule. Currently, if we use
* ActiveTestRule as a @Rule, then end-user @Before methods will execute
* <em>first</em> and any fields we're supposed to supply will be
* <code>null</code>.
*/
@Before
public final void initMocks() {
activeTestrule.initMocks(this);
}
}
Show details Hide details

Change log

r83 by aisrael on Oct 17, 2009   Diff
Interceptor -> Rule
Go to: 
Project members, sign in to write a code review

Older revisions

r73 by aisrael on Oct 17, 2009   Diff
Make ActiveTest still delegate to an
ActiveTestInterceptor (for now), but
not as a @Rule. Change it back when
JUnit > 4.7
r19 by aisrael on Aug 13, 2009   Diff
`dirty-mockito-0.2`: now uses JUnit
4.7's interceptors to perfom test
harness setupĀ (mocking & injection)
r9 by aisrael on May 29, 2009   Diff
Moved the uncheck typecast to
ActiveTest#determineTypeParameter()
All revisions of this file

File info

Size: 4348 bytes, 130 lines
Hosted by Google Code