Search code examples
jmockit

jmockit - Mocking chain of methods one of which returns a Collection using @Cascading


I am trying to mock a method call which goes something like this:

rapContext.getSysInfo().get(key)

The getSysInfo() method returns a ConcurrentHashMap.

Here is what I have done:

Class ABCTest {
    @Cascading RapContext context;

    @Test
    doTest() {
      new Expectations() {

        {
        rapContext.getSysInfo().get(anyString);
            result = new UserPrefCtxObject();
         }
      }
    }

With this I get a NullPointerException on rapContext.getSysInfo(). Call to getSysInfo() returns null. If I call any other method which does not return a collection, for instance rapContext.getDomain() everything working fine.

I am not sure what I am missing.

Thanks


Solution

  • The code example is not complete however you are likely running into some issue associated with accidentally mocking Map. If a Map (or any part of the Collection framework) is mocked then a lot of things will break. I could not reproduce your problem as any attempt to mock RapContext using @Cascading resulted in a stack over flow.

    You could partially mock RapContext instead and then either return a real or mocked Map. When I run into similar issues I generally get around them using either @Injectable to only mock an instance of a class or using partial mocks.

    Here is an approach that will let you mock getSysInfo:

       public class RapContextTest {
    
        @Injectable ConcurrentHashMap<String, Object> mockedMap;
    
        @Test
        public void testContext() {
            RapContext context = new RapContext();
    
            new MockUp<RapContext>(){
                @Mock
                public ConcurrentHashMap getSysInfo(){
                    return mockedMap;
                }
    
            };
    
            new NonStrictExpectations() {
                {
                    mockedMap.get(anyString);
                    result = "Success";
    
                }
            };
    
            Object value = context.getSysInfo().get("test");
            System.out.println(value);
    
        }
    }