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 49 @Before public void before() { 50 MockitoAnnotations.initMocks(this); 51 } 52 53 @Test 54 public void shouldNotFailWhenNotInitialized() { 55 assertNotNull(articleManager); 56 } 57 58 @Test(expected = IllegalArgumentException.class) 59 public void innerMockShouldRaiseAnExceptionThatChangesOuterMockBehavior() { 60 when(calculator.countArticles("new")).thenThrow(new IllegalArgumentException()); 61 62 articleManager.updateArticleCounters("new"); 63 } 64 65 @Test 66 public void mockJustWorks() { 67 articleManager.updateArticleCounters("new"); 68 } 69 70 @Test 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 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 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 110 @Test public void test_1() { } 111 @Test public void test_2() { } 112 @Test public void test_3() { } 113 114 private static class some_class_with_parametered_constructor { 115 public some_class_with_parametered_constructor(List<?> collaborator) { 116 constructor_instantiation++; 117 } 118 } 119 } 120 121 private static class FailingConstructor { 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 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 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 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 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 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 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