Home | History | Annotate | Download | only in annotation
      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