Skip to content

Commit

Permalink
Fixed mockito#538 changed error message in case initialization for mock
Browse files Browse the repository at this point in the history
injection fails.
  • Loading branch information
Christian Schwarz committed Aug 14, 2016
1 parent f80dd4a commit 3f1b9a2
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 18 deletions.
Expand Up @@ -98,7 +98,7 @@ private FieldInitializationReport initializeInjectMocksField(Field field, Object
Throwable realCause = e.getCause().getCause();
throw fieldInitialisationThrewException(field, realCause);
}
throw cannotInitializeForInjectMocksAnnotation(field.getName(), e);
throw cannotInitializeForInjectMocksAnnotation(field.getName(),e.getMessage());
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/main/java/org/mockito/internal/exceptions/Reporter.java
Expand Up @@ -627,16 +627,14 @@ public static MockitoException cannotInitializeForSpyAnnotation(String fieldName
""), details);
}

public static MockitoException cannotInitializeForInjectMocksAnnotation(String fieldName, Exception details) {
return new MockitoException(join("Cannot instantiate @InjectMocks field named '" + fieldName + "'.",
public static MockitoException cannotInitializeForInjectMocksAnnotation(String fieldName, String causeMessage) {
return new MockitoException(join("Cannot instantiate @InjectMocks field named '" + fieldName + "'! Cause: "+causeMessage,
"You haven't provided the instance at field declaration so I tried to construct the instance.",
"However, I failed because: " + details.getMessage(),
"Examples of correct usage of @InjectMocks:",
" @InjectMocks Service service = new Service();",
" @InjectMocks Service service;",
" //also, don't forget about MockitoAnnotations.initMocks();",
" //and... don't forget about some @Mocks for injection :)",
""), details);
""));
}

public static MockitoException atMostAndNeverShouldNotBeUsedWithTimeout() {
Expand Down
Expand Up @@ -7,6 +7,7 @@
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.MockUtil;

import static java.lang.reflect.Modifier.isStatic;
import static org.mockito.internal.util.reflection.FieldSetter.setField;

import java.lang.reflect.Constructor;
Expand Down Expand Up @@ -68,7 +69,9 @@ private FieldInitializer(Object fieldOwner, Field field, ConstructorInstantiator
checkNotLocal(field);
checkNotInner(field);
checkNotInterface(field);
checkNotEnum(field);
checkNotAbstract(field);

}
this.fieldOwner = fieldOwner;
this.field = field;
Expand Down Expand Up @@ -100,8 +103,9 @@ private void checkNotLocal(Field field) {
}

private void checkNotInner(Field field) {
if(field.getType().isMemberClass() && !Modifier.isStatic(field.getType().getModifiers())) {
throw new MockitoException("the type '" + field.getType().getSimpleName() + "' is an inner class.");
Class<?> type = field.getType();
if(type.isMemberClass() && !isStatic(type.getModifiers())) {
throw new MockitoException("the type '" + type.getSimpleName() + "' is an inner non static class.");
}
}

Expand All @@ -113,10 +117,17 @@ private void checkNotInterface(Field field) {

private void checkNotAbstract(Field field) {
if(Modifier.isAbstract(field.getType().getModifiers())) {
throw new MockitoException("the type '" + field.getType().getSimpleName() + " is an abstract class.");
throw new MockitoException("the type '" + field.getType().getSimpleName() + "' is an abstract class.");
}
}

private void checkNotEnum(Field field) {
if(field.getType().isEnum()) {
throw new MockitoException("the type '" + field.getType().getSimpleName() + "' is an enum.");
}
}


private FieldInitializationReport acquireFieldInstance() throws IllegalAccessException {
Object fieldInstance = field.get(fieldOwner);
if(fieldInstance != null) {
Expand Down
Expand Up @@ -5,9 +5,24 @@

package org.mockitousage.annotation;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import java.util.AbstractCollection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.assertj.core.api.Assertions;
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;
Expand All @@ -17,17 +32,11 @@
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.MockUtil;
import org.mockito.runners.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.List;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class MockInjectionUsingConstructorTest {

Expand All @@ -37,8 +46,8 @@ public class MockInjectionUsingConstructorTest {
@InjectMocks private ArticleManager articleManager;
@Spy @InjectMocks private ArticleManager spiedArticleManager;


// @InjectMocks private ArticleVisitor should_be_initialized_3_times;
@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void shouldNotFailWhenNotInitialized() {
Expand Down Expand Up @@ -120,5 +129,91 @@ private static class ATest {
@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);
}




}
Expand Up @@ -6,7 +6,9 @@
package org.mockitousage.basicapi;

import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.exceptions.verification.SmartNullPointerException;
import org.mockito.internal.debugging.LocationImpl;
Expand All @@ -16,6 +18,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static junit.framework.TestCase.*;
import static org.assertj.core.api.Assertions.assertThat;
Expand Down

0 comments on commit 3f1b9a2

Please sign in to comment.