4

It's been two days that I am trying to solve this! Here is the thing: I have a Class as below:


public class TaskEntity extends Index {

    public String title;
    public String description;
    public UUID posterId;
    public Long time;
    public String address;
    public GeoPoint location;

    public static Finder find = new Finder(TaskEntity.class);

    //some methods
}

which extends this abstract class:


public abstract class Index implements Indexable {
    //some public non static fields
    // some methods

    public static class Finder {
        private final Class type;
        private IndexQueryPath queryPath;

        public Finder(Class type) {
            this.type = type;
            T t = IndexUtils.getInstanceIndex(type); // error here!
            this.queryPath = t.getIndexPath();
        }

        public IndexQueryPath getIndexPath() {

            IndexType indexTypeAnnotation = this.getClass().getAnnotation(IndexType.class);
            if(indexTypeAnnotation == null) {
                Logger.error("ElasticSearch : Class " + this.getClass().getCanonicalName() + " no contain @IndexType(name) annotation ");
            }
            String indexType = indexTypeAnnotation.name();

            String indexName = IndexService.INDEX_DEFAULT; // This is not defined, therefore throw a NullPointerException
            IndexName indexNameAnnotation = this.getClass().getAnnotation(IndexName.class);
            if(indexNameAnnotation != null) {
                indexName = indexNameAnnotation.name();
            }

               return new IndexQueryPath(indexName, indexType);
         }

        // some methods
    }

}

Simply I try to mock the TaskEntity class without any extra code as below:


public class TaskManagementServiceImplTest {
    @Mock
    private TaskEntity taskEntity;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void emptyTest(){

    }
}

BOOM:


java.lang.ExceptionInInitializerError
    at com.github.cleverage.elasticsearch.Index.getIndexPath(Index.java:41)
    at com.github.cleverage.elasticsearch.Index$Finder.(Index.java:164)
    at models.elasticsearch.TaskEntity.(TaskEntity.java:48)
    at sun.reflect.GeneratedSerializationConstructorAccessor6.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45)
    at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63)
    at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:111)
    at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:60)
    at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:143)
    at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:84)
    at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:51)
    at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:90)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:292)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
    at com.github.cleverage.elasticsearch.IndexService.(IndexService.java:45)
    ... 36 more


I am mocking my TaskEntity class to avoid initializing my search engine. However, as I can see even when I want to mock it it tries to access stuff that it shouldn't. Is there a way to avoid this? Is there a way to mock TaskEntity and somehow ignoring that "find" field? Any help is appreciated!

Hossein
  • 40,161
  • 57
  • 141
  • 175
  • Just to make sure I got the question right, you want to mock `TaskEntity` at the highest level? You don't want the code going into this `Finder` constructor? You want to mock a `TaskEntity` and manipulate the `Finder` inside of it, without it firing off using the normal coded functionality? – Walls Apr 23 '14 at 14:04
  • Yes, I don't want the code going into this Finder constructor. – Hossein Apr 23 '14 at 14:39

1 Answers1

1

I think the easy solution is to mock the IndexUtils.getInstanceIndex(type) call. That looks like a static call which is setting that t variable, which is then trying to be used in the next line t.getIndexPath();. When mocking the static IndexUtils, make sure to include in your @PrepareForTest annotation at least IndexUtils and Finder. This would need to be handled in your setUp() but before you try and initMocks(this). That way, when the execution gets to the error line (upon initialization of the TaskEntity mock) it will have the hooks to return the proper mocked values to continue with the setup.

If you want the code to not go into the Finder constructor at all, it could take a few more hoops to jump through. Your setup would have to change a bit to handle the static. Make sure to still include Finder as well as TaskEntity in your @PrepareTest annotation.

@Mock
private TaskEntity taskEntity;
@Mock
private Finder findMock;

@Before
public void setUp() throws Exception {
  PowerMockito.mockStatic(Finder.class);
  PowerMockito.whenNew(Finder.class).withArguments(TaskEntity.class).thenReturn(findMock);
  MockitoAnnotations.initMocks(this);
}

@Test
public void emptyTest(){

}

This above code is a little tricky and I am not sure if it will work for you. I am having trouble creating some shell classes locally to do testing with. I tried simplifying the ones you provided but I am still trying to grasp the setup and correlation between all the complex objects you have. If there are any errors with this, let me know and I can try and debug through them.

Walls
  • 3,972
  • 6
  • 37
  • 52