Метод Mock Interface по умолчанию - PullRequest
0 голосов
/ 24 февраля 2020

Я пытаюсь смоделировать метод по умолчанию (который использует SecurityContextHolder для входа в систему) интерфейса, но не могу смоделировать.

public interface BaseController {

    /**
     * @return loggedInUser name
     */
    default String getLoggedInUser() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication.getName();
    }
}
public class WPController implements BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(WPController.class);

    private WPService wpService;

    /**
     * @return ResponseEntity<List<WPDTO>>
     */
    @GetMapping("/all")
    public ResponseEntity<List<WPDTO>> getWPs() {
        LOG.debug("Calling.... all wp by user: {}", getLoggedInUser());
        final List<WPDTO> allWP = wpService.getAllWP();
        //LOG.debug("Called all wps by user: {}", getLoggedInUser());
        return ResponseEntity.ok(allWP );
    }
@RunWith(PowerMockRunner.class)
public class WPControllerTest {

    @Mock
    WPService wpService;

    @Mock
    private Logger loggerMock;

    @PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "javax.management.*", "javax.security.*"})
    @PrepareForTest({ LoggerFactory.class, BaseController.class })
    @Test
    public void  getWPsTest()
    {
        List<WPDTO> list = new ArrayList<>();
        WPDTO wpDTO= new WPDTO();
        wpDTO.setId(1);
        wpDTO.setDescription("Description");
        wpDTO.setLabel("Label");
        list.add(wpDTO);

        Authentication mockAuthentication = Mockito.mock(Authentication.class);

        BaseController baseController = Mockito.mock(BaseController.class);
        PowerMockito.when(baseController.getLoggedInUser()).thenReturn("Test User");

        mockStatic(LoggerFactory.class);
        PowerMockito.when(LoggerFactory.getLogger(WPServiceImpl.class)).thenReturn(loggerMock);

        Mockito.when(wpService.getAllWP()).thenReturn(list);

        WPController wpController = new WPController();
        wpController .setWPService(wpService);

        ResponseEntity<List<WPDTO>> response = wpController.getWPs();
        assertNotNull(response);
        assertTrue(response.getBody().size()>0);
    }
}

Ошибка:

java.lang.NullPointerException
    at com.odigo.supervision.workspace.rest.BaseController.getLoggedInUser(BaseController.java:19)
    at com.odigo.supervision.workspace.rest.WorkspaceController.getWorkspaces(WorkspaceController.java:34)
    at com.odigo.supervision.workspace.rest.WorkspaceControllerTest.getWorkspacesTest(WorkspaceControllerTest.java:76)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

1 Ответ

0 голосов
/ 26 февраля 2020

Я бы не использовал PowerMockito для этого. Вы можете сделать WPController шпионом, что означает, что это реально, но методы могут быть превращены в шутки. В этом случае, я думаю, что самый простой способ сделать это - использовать @InjectMocks, который создает действительное WPController и заменяет действительные поля в нем любыми @Mock классами в тестовом классе. Затем также добавьте @Spy, чтобы сделать его шпионом. Некоторые люди не думают, что это хороший шаблон , но я думаю, что это лучшее решение для вашего дизайна.

После такой настройки легко переопределить getLoggedInUser() для вызова фиктивной реализации.

@RunWith(MockitoJUnitRunner.class)
public class WPControllerTest {

    @InjectMocks
    @Spy
    WPController wpController;

    @Mock
    WPService wpService;

    @Test
    public void  getWPsTest()
    {
        List<WPDTO> list = new ArrayList<>();
        WPDTO wpDTO= new WPDTO();
        wpDTO.setId(1);
        wpDTO.setDescription("Description");
        wpDTO.setLabel("Label");
        list.add(wpDTO);

        Mockito.doReturn("Test User").when(wpController).getLoggedInUser();
        Mockito.when(wpService.getAllWP()).thenReturn(list);

        ResponseEntity<List<WPDTO>> response = wpController.getWPs();
        assertNotNull(response);
        assertEquals(wpDTO, response.getBody().get(0));
    }
}
...