• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 
6 package org.mockitousage.annotation;
7 
8 import org.junit.Before;
9 import org.junit.Ignore;
10 import org.junit.Rule;
11 import org.junit.Test;
12 import org.junit.internal.TextListener;
13 import org.junit.rules.ExpectedException;
14 import org.junit.runner.JUnitCore;
15 import org.junit.runner.RunWith;
16 import org.mockito.InjectMocks;
17 import org.mockito.Mock;
18 import org.mockito.MockitoAnnotations;
19 import org.mockito.Spy;
20 import org.mockito.exceptions.base.MockitoException;
21 import org.mockito.internal.util.MockUtil;
22 import org.mockito.junit.MockitoJUnitRunner;
23 import org.mockitousage.IMethods;
24 import org.mockitousage.examples.use.ArticleCalculator;
25 import org.mockitousage.examples.use.ArticleDatabase;
26 import org.mockitousage.examples.use.ArticleManager;
27 
28 import java.util.AbstractCollection;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.concurrent.TimeUnit;
32 
33 import static org.assertj.core.api.Assertions.assertThat;
34 import static org.junit.Assert.*;
35 import static org.mockito.Mockito.when;
36 import static org.mockito.MockitoAnnotations.initMocks;
37 
38 public class MockInjectionUsingConstructorTest {
39 
40     @Mock private ArticleCalculator calculator;
41     @Mock private ArticleDatabase database;
42 
43     @InjectMocks private ArticleManager articleManager;
44     @Spy @InjectMocks private ArticleManager spiedArticleManager;
45 
46     @Rule
47     public ExpectedException exception = ExpectedException.none();
48 
before()49     @Before public void before() {
50         MockitoAnnotations.initMocks(this);
51     }
52 
53     @Test
shouldNotFailWhenNotInitialized()54     public void shouldNotFailWhenNotInitialized() {
55         assertNotNull(articleManager);
56     }
57 
58     @Test(expected = IllegalArgumentException.class)
innerMockShouldRaiseAnExceptionThatChangesOuterMockBehavior()59     public void innerMockShouldRaiseAnExceptionThatChangesOuterMockBehavior() {
60         when(calculator.countArticles("new")).thenThrow(new IllegalArgumentException());
61 
62         articleManager.updateArticleCounters("new");
63     }
64 
65     @Test
mockJustWorks()66     public void mockJustWorks() {
67         articleManager.updateArticleCounters("new");
68     }
69 
70     @Test
constructor_is_called_for_each_test_in_test_class()71     public void constructor_is_called_for_each_test_in_test_class() throws Exception {
72         // given
73         junit_test_with_3_tests_methods.constructor_instantiation = 0;
74         JUnitCore jUnitCore = new JUnitCore();
75         jUnitCore.addListener(new TextListener(System.out));
76 
77         // when
78         jUnitCore.run(junit_test_with_3_tests_methods.class);
79 
80         // then
81         assertThat(junit_test_with_3_tests_methods.constructor_instantiation).isEqualTo(3);
82     }
83 
84     @Test
objects_created_with_constructor_initialization_can_be_spied()85     public void objects_created_with_constructor_initialization_can_be_spied() throws Exception {
86         assertFalse(MockUtil.isMock(articleManager));
87         assertTrue(MockUtil.isMock(spiedArticleManager));
88     }
89 
90     @Test
should_report_failure_only_when_object_initialization_throws_exception()91     public void should_report_failure_only_when_object_initialization_throws_exception() throws Exception {
92 
93         try {
94             MockitoAnnotations.initMocks(new ATest());
95             fail();
96         } catch (MockitoException e) {
97             assertThat(e.getMessage()).contains("failingConstructor").contains("constructor").contains("threw an exception");
98             assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
99         }
100     }
101 
102 
103     @RunWith(MockitoJUnitRunner.class)
104     public static class junit_test_with_3_tests_methods {
105         private static int constructor_instantiation = 0;
106 
107         @Mock List<?> some_collaborator;
108         @InjectMocks some_class_with_parametered_constructor should_be_initialized_3_times;
109 
test_1()110         @Test public void test_1() { }
test_2()111         @Test public void test_2() { }
test_3()112         @Test public void test_3() { }
113 
114         private static class some_class_with_parametered_constructor {
some_class_with_parametered_constructor(List<?> collaborator)115             public some_class_with_parametered_constructor(List<?> collaborator) {
116                 constructor_instantiation++;
117             }
118         }
119     }
120 
121     private static class FailingConstructor {
FailingConstructor(Set<?> set)122         FailingConstructor(Set<?> set) {
123             throw new IllegalStateException("always fail");
124         }
125     }
126 
127     @Ignore("don't run this code in the test runner")
128     private static class ATest {
129         @Mock Set<?> set;
130         @InjectMocks FailingConstructor failingConstructor;
131     }
132 
133 
134     @Test
injectMocksMustFailWithInterface()135     public void injectMocksMustFailWithInterface() throws Exception {
136         class TestCase {
137             @InjectMocks
138             IMethods f;
139         }
140 
141         exception.expect(MockitoException.class);
142         exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'IMethods' is an interface");
143 
144 
145         initMocks(new TestCase());
146     }
147 
148     @Test
injectMocksMustFailWithEnum()149     public void injectMocksMustFailWithEnum() throws Exception {
150         class TestCase {
151             @InjectMocks
152             TimeUnit f;
153         }
154 
155         exception.expect(MockitoException.class);
156         exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'TimeUnit' is an enum");
157 
158         initMocks(new TestCase());
159     }
160 
161     @Test
injectMocksMustFailWithAbstractClass()162     public void injectMocksMustFailWithAbstractClass() throws Exception {
163         class TestCase {
164             @InjectMocks
165             AbstractCollection<?> f;
166         }
167 
168         exception.expect(MockitoException.class);
169         exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'AbstractCollection' is an abstract class");
170 
171         initMocks(new TestCase());
172     }
173 
174     @Test
injectMocksMustFailWithNonStaticInnerClass()175     public void injectMocksMustFailWithNonStaticInnerClass() throws Exception {
176         class TestCase {
177             class InnerClass {}
178             @InjectMocks
179             InnerClass f;
180         }
181 
182 
183         exception.expect(MockitoException.class);
184         exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'InnerClass' is an inner non static class");
185 
186         initMocks(new TestCase());
187     }
188 
189     static class  StaticInnerClass {}
190     @Test
injectMocksMustSucceedWithStaticInnerClass()191     public void injectMocksMustSucceedWithStaticInnerClass() throws Exception {
192         class TestCase {
193             @InjectMocks
194             StaticInnerClass f;
195         }
196 
197         TestCase testClass = new TestCase();
198         initMocks(testClass);
199 
200         assertThat(testClass.f).isInstanceOf(StaticInnerClass.class);
201     }
202 
203     @Test
injectMocksMustSucceedWithInstance()204     public void injectMocksMustSucceedWithInstance() throws Exception {
205         class TestCase {
206             @InjectMocks
207             StaticInnerClass f = new StaticInnerClass();
208         }
209 
210         TestCase testClass = new TestCase();
211         StaticInnerClass original = testClass.f;
212         initMocks(testClass);
213 
214         assertThat(testClass.f).isSameAs(original);
215     }
216 
217 
218 
219 
220 }
221