1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockitousage.annotation; 6 7 import static org.junit.Assert.*; 8 9 import java.util.List; 10 import java.util.Map; 11 import java.util.Set; 12 import java.util.TreeSet; 13 14 import org.assertj.core.api.Assertions; 15 import org.junit.After; 16 import org.junit.Before; 17 import org.junit.Test; 18 import org.mockito.InjectMocks; 19 import org.mockito.Mock; 20 import org.mockito.MockitoAnnotations; 21 import org.mockito.Spy; 22 import org.mockito.exceptions.base.MockitoException; 23 import org.mockito.internal.util.MockUtil; 24 import org.mockitousage.IMethods; 25 import org.mockitoutil.TestBase; 26 27 @SuppressWarnings({"unchecked", "unused"}) 28 public class MockInjectionUsingSetterOrPropertyTest extends TestBase { 29 30 private SuperUnderTesting superUnderTestWithoutInjection = new SuperUnderTesting(); 31 @InjectMocks private SuperUnderTesting superUnderTest = new SuperUnderTesting(); 32 @InjectMocks private BaseUnderTesting baseUnderTest = new BaseUnderTesting(); 33 @InjectMocks private SubUnderTesting subUnderTest = new SubUnderTesting(); 34 @InjectMocks private OtherBaseUnderTesting otherBaseUnderTest = new OtherBaseUnderTesting(); 35 36 @InjectMocks 37 private HasTwoFieldsWithSameType hasTwoFieldsWithSameType = new HasTwoFieldsWithSameType(); 38 39 private BaseUnderTesting baseUnderTestingInstance = new BaseUnderTesting(); 40 @InjectMocks private BaseUnderTesting initializedBase = baseUnderTestingInstance; 41 @InjectMocks private BaseUnderTesting notInitializedBase; 42 43 @Spy @InjectMocks private SuperUnderTesting initializedSpy = new SuperUnderTesting(); 44 @Spy @InjectMocks private SuperUnderTesting notInitializedSpy; 45 46 @Mock private Map<?, ?> map; 47 @Mock private List<?> list; 48 @Mock private Set<?> histogram1; 49 @Mock private Set<?> histogram2; 50 @Mock private IMethods candidate2; 51 52 @Spy private TreeSet<String> searchTree = new TreeSet<String>(); 53 54 private AutoCloseable session; 55 56 @Before enforces_new_instances()57 public void enforces_new_instances() { 58 // openMocks called in TestBase Before method, so instances are not the same 59 session = MockitoAnnotations.openMocks(this); 60 } 61 62 @After close_new_instances()63 public void close_new_instances() throws Exception { 64 if (session != null) { 65 session.close(); 66 } 67 } 68 69 @Test should_keep_same_instance_if_field_initialized()70 public void should_keep_same_instance_if_field_initialized() { 71 assertSame(baseUnderTestingInstance, initializedBase); 72 } 73 74 @Test should_initialize_annotated_field_if_null()75 public void should_initialize_annotated_field_if_null() { 76 assertNotNull(notInitializedBase); 77 } 78 79 @Test should_inject_mocks_in_spy()80 public void should_inject_mocks_in_spy() { 81 assertNotNull(initializedSpy.getAList()); 82 assertTrue(MockUtil.isMock(initializedSpy)); 83 } 84 85 @Test should_initialize_spy_if_null_and_inject_mocks()86 public void should_initialize_spy_if_null_and_inject_mocks() { 87 assertNotNull(notInitializedSpy); 88 assertNotNull(notInitializedSpy.getAList()); 89 assertTrue(MockUtil.isMock(notInitializedSpy)); 90 } 91 92 @Test should_inject_mocks_if_annotated()93 public void should_inject_mocks_if_annotated() { 94 MockitoAnnotations.openMocks(this); 95 assertSame(list, superUnderTest.getAList()); 96 } 97 98 @Test should_not_inject_if_not_annotated()99 public void should_not_inject_if_not_annotated() { 100 MockitoAnnotations.openMocks(this); 101 assertNull(superUnderTestWithoutInjection.getAList()); 102 } 103 104 @Test should_inject_mocks_for_class_hierarchy_if_annotated()105 public void should_inject_mocks_for_class_hierarchy_if_annotated() { 106 MockitoAnnotations.openMocks(this); 107 assertSame(list, baseUnderTest.getAList()); 108 assertSame(map, baseUnderTest.getAMap()); 109 } 110 111 @Test should_inject_mocks_by_name()112 public void should_inject_mocks_by_name() { 113 MockitoAnnotations.openMocks(this); 114 assertSame(histogram1, subUnderTest.getHistogram1()); 115 assertSame(histogram2, subUnderTest.getHistogram2()); 116 } 117 118 @Test should_inject_spies()119 public void should_inject_spies() { 120 MockitoAnnotations.openMocks(this); 121 assertSame(searchTree, otherBaseUnderTest.getSearchTree()); 122 } 123 124 @Test 125 public void should_insert_into_field_with_matching_name_when_multiple_fields_of_same_type_exists_in_injectee()126 should_insert_into_field_with_matching_name_when_multiple_fields_of_same_type_exists_in_injectee() { 127 MockitoAnnotations.openMocks(this); 128 assertNull("not injected, no mock named 'candidate1'", hasTwoFieldsWithSameType.candidate1); 129 assertNotNull( 130 "injected, there's a mock named 'candidate2'", hasTwoFieldsWithSameType.candidate2); 131 } 132 133 @Test should_instantiate_inject_mock_field_if_possible()134 public void should_instantiate_inject_mock_field_if_possible() throws Exception { 135 assertNotNull(notInitializedBase); 136 } 137 138 @Test should_keep_instance_on_inject_mock_field_if_present()139 public void should_keep_instance_on_inject_mock_field_if_present() throws Exception { 140 assertSame(baseUnderTestingInstance, initializedBase); 141 } 142 143 @Test should_report_nicely()144 public void should_report_nicely() throws Exception { 145 Object failing = 146 new Object() { 147 @InjectMocks ThrowingConstructor failingConstructor; 148 }; 149 try { 150 MockitoAnnotations.openMocks(failing); 151 fail(); 152 } catch (MockitoException e) { 153 Assertions.assertThat(e.getMessage()) 154 .contains("failingConstructor") 155 .contains("constructor") 156 .contains("threw an exception"); 157 Assertions.assertThat(e.getCause()).isInstanceOf(RuntimeException.class); 158 } 159 } 160 161 static class ThrowingConstructor { ThrowingConstructor()162 ThrowingConstructor() { 163 throw new RuntimeException("aha"); 164 } 165 } 166 167 static class SuperUnderTesting { 168 private List<?> aList; 169 getAList()170 public List<?> getAList() { 171 return aList; 172 } 173 } 174 175 static class BaseUnderTesting extends SuperUnderTesting { 176 private Map<?, ?> aMap; 177 getAMap()178 public Map<?, ?> getAMap() { 179 return aMap; 180 } 181 } 182 183 static class OtherBaseUnderTesting extends SuperUnderTesting { 184 private TreeSet<?> searchTree; 185 getSearchTree()186 public TreeSet<?> getSearchTree() { 187 return searchTree; 188 } 189 } 190 191 static class SubUnderTesting extends BaseUnderTesting { 192 private Set<?> histogram1; 193 private Set<?> histogram2; 194 getHistogram1()195 public Set<?> getHistogram1() { 196 return histogram1; 197 } 198 getHistogram2()199 public Set<?> getHistogram2() { 200 return histogram2; 201 } 202 } 203 204 static class HasTwoFieldsWithSameType { 205 private IMethods candidate1; 206 private IMethods candidate2; 207 } 208 } 209