blob: 38879dcc92d6da78cc78162534961546e09ce1b3 [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockitousage.annotation;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.internal.TextListener;
import org.junit.rules.ExpectedException;
import org.junit.runner.JUnitCore;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.MockUtil;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockitousage.IMethods;
import org.mockitousage.examples.use.ArticleCalculator;
import org.mockitousage.examples.use.ArticleDatabase;
import org.mockitousage.examples.use.ArticleManager;
import java.util.AbstractCollection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
public class MockInjectionUsingConstructorTest {
@Mock private ArticleCalculator calculator;
@Mock private ArticleDatabase database;
@InjectMocks private ArticleManager articleManager;
@Spy @InjectMocks private ArticleManager spiedArticleManager;
@Rule
public ExpectedException exception = ExpectedException.none();
@Before public void before() {
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldNotFailWhenNotInitialized() {
assertNotNull(articleManager);
}
@Test(expected = IllegalArgumentException.class)
public void innerMockShouldRaiseAnExceptionThatChangesOuterMockBehavior() {
when(calculator.countArticles("new")).thenThrow(new IllegalArgumentException());
articleManager.updateArticleCounters("new");
}
@Test
public void mockJustWorks() {
articleManager.updateArticleCounters("new");
}
@Test
public void constructor_is_called_for_each_test_in_test_class() throws Exception {
// given
junit_test_with_3_tests_methods.constructor_instantiation = 0;
JUnitCore jUnitCore = new JUnitCore();
jUnitCore.addListener(new TextListener(System.out));
// when
jUnitCore.run(junit_test_with_3_tests_methods.class);
// then
assertThat(junit_test_with_3_tests_methods.constructor_instantiation).isEqualTo(3);
}
@Test
public void objects_created_with_constructor_initialization_can_be_spied() throws Exception {
assertFalse(MockUtil.isMock(articleManager));
assertTrue(MockUtil.isMock(spiedArticleManager));
}
@Test
public void should_report_failure_only_when_object_initialization_throws_exception() throws Exception {
try {
MockitoAnnotations.initMocks(new ATest());
fail();
} catch (MockitoException e) {
assertThat(e.getMessage()).contains("failingConstructor").contains("constructor").contains("threw an exception");
assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
}
}
@RunWith(MockitoJUnitRunner.class)
public static class junit_test_with_3_tests_methods {
private static int constructor_instantiation = 0;
@Mock List<?> some_collaborator;
@InjectMocks some_class_with_parametered_constructor should_be_initialized_3_times;
@Test public void test_1() { }
@Test public void test_2() { }
@Test public void test_3() { }
private static class some_class_with_parametered_constructor {
public some_class_with_parametered_constructor(List<?> collaborator) {
constructor_instantiation++;
}
}
}
private static class FailingConstructor {
FailingConstructor(Set<?> set) {
throw new IllegalStateException("always fail");
}
}
@Ignore("don't run this code in the test runner")
private static class ATest {
@Mock Set<?> set;
@InjectMocks FailingConstructor failingConstructor;
}
@Test
public void injectMocksMustFailWithInterface() throws Exception {
class TestCase {
@InjectMocks
IMethods f;
}
exception.expect(MockitoException.class);
exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'IMethods' is an interface");
initMocks(new TestCase());
}
@Test
public void injectMocksMustFailWithEnum() throws Exception {
class TestCase {
@InjectMocks
TimeUnit f;
}
exception.expect(MockitoException.class);
exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'TimeUnit' is an enum");
initMocks(new TestCase());
}
@Test
public void injectMocksMustFailWithAbstractClass() throws Exception {
class TestCase {
@InjectMocks
AbstractCollection<?> f;
}
exception.expect(MockitoException.class);
exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'AbstractCollection' is an abstract class");
initMocks(new TestCase());
}
@Test
public void injectMocksMustFailWithNonStaticInnerClass() throws Exception {
class TestCase {
class InnerClass {}
@InjectMocks
InnerClass f;
}
exception.expect(MockitoException.class);
exception.expectMessage("Cannot instantiate @InjectMocks field named 'f'! Cause: the type 'InnerClass' is an inner non static class");
initMocks(new TestCase());
}
static class StaticInnerClass {}
@Test
public void injectMocksMustSucceedWithStaticInnerClass() throws Exception {
class TestCase {
@InjectMocks
StaticInnerClass f;
}
TestCase testClass = new TestCase();
initMocks(testClass);
assertThat(testClass.f).isInstanceOf(StaticInnerClass.class);
}
@Test
public void injectMocksMustSucceedWithInstance() throws Exception {
class TestCase {
@InjectMocks
StaticInnerClass f = new StaticInnerClass();
}
TestCase testClass = new TestCase();
StaticInnerClass original = testClass.f;
initMocks(testClass);
assertThat(testClass.f).isSameAs(original);
}
}