Search code examples
junitmockitojava-17jmockit

Mockit to Mockito: Enum Constant method implementations count using mockito


public void testActionsThatNeedVerifyingPermissionsBeforeExecution()
    {
        IntegerWrapper value = new IntegerWrapper(0);
        new MockUp<HyperlinkActionType>()
        {
            @SuppressWarnings("ParameterHidesMemberVariable")
            @Mock
            void performActionIfApplicable(String entityId)
            {
                value.increment();
            }
        };

        //noinspection ConstantConditions
        Arrays.stream(HyperlinkActionType.values()).forEach(action -> action.invokeRequest(null));

        Assert.assertEquals("Except SAVE all other actions need to pass through 'performActionIfApplicable'"
                ,1,value.getWrappedObject().intValue());
    }

Enum Code

public enum HyperlinkActionType
{
    EDIT("Edit") {
        @Override public void invokeRequest(String entityId)
        {
            performActionIfApplicable(
                    entityId);
        }

    }

////////////

    DONOTHING("Donothing") {
        @Override public void invokeRequest(String entityId)
        {
            
        }
    }
    public void invokeRequest(String entityId)
    {
    }

    void performActionIfApplicable(String entityId) 
        {
                  ...

        }

}

This test is running invokeRequest mehtod on Enum.values and expecting the count for performActionIfApplicable will be 1 I am working on java17 and we are migrating to jmockit to mockito.

I am expecting to get the count 1 when invokeRequest is called on both enum constants(enum.values) as EDIT can only performActionIfApplicable through invokeRequest

Solution: spy on each enum value


Solution

  • Spy on each enum value and use doAnswer to increment the a value

        @Test
        public void testActionsThatNeedVerifyingPermissionsBeforeExecution()
        {
    
            int actionsThatNeedVerificationBeforeExecution = 0;
            for (HyperlinkActionType hyperlinkActionType : HyperlinkActionType.values()) {
                actionsThatNeedVerificationBeforeExecution += testEachActionTypeForVerification(hyperlinkActionType);
            }
            Assert.assertEquals("Except DONOTHING all other actions need to pass through 'performActionIfApplicable'"
                    , 1, actionsThatNeedVerificationBeforeExecution);
        }
    
        private int testEachActionTypeForVerification(HyperlinkActionType edit)
        {
            HyperlinkActionType spyiedAction = Mockito.spy(edit);
            IntegerWrapper willVerify = new IntegerWrapper(0);
    
            Mockito.doAnswer((i) -> {
                        willVerify.increment(); // This will only increment if performActionIfAvailable is called
                        return null;
                    })
                    .when(spyiedAction)
                    .performActionIfApplicable(Mockito.isNull());
    
            spyiedAction.invokeRequest(null);
            return willVerify.getWrappedObject().intValue(); //it will return 1 if performACtionIfApplicable is called othewise ZERO
        }