Как издеваться с MockHttpSession и Junit - PullRequest
0 голосов
/ 01 октября 2019

Посмотрел этот пост , где @ slim дал решение, близкое к тому, о чем я спрашиваю. Я пытаюсь написать модульный тест по классу ниже. Я вытаскиваю идентификатор сессии. ( ищите String sessId внутри метода doFilterInternal )

@Component
public class AppLoggingFilter extends OncePerRequestFilter {

    private AppLoggingMDCService mdcService;

    @Inject
    public AppLoggingFilter(AppLoggingMDCService appLoggingMDCService) {
        Assert.notNull(appLoggingMDCService, "AppLoggingMDCService must not be null");
        this.mdcService = appLoggingMDCService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {   

        Principal principal = request.getUserPrincipal();
        String sessId = DigestUtils.sha256Hex(request.getSession().getId());

        if (principal != null) {
            String userId = principal.getName();
            mdcService.put(AppLoggingMDCService.LOG_KEY_USER_ID, userId);
        }
        mdcService.put(AppLoggingMDCService.LOG_KEY_SESSION_ID, sessId);
        try {
        filterChain.doFilter(request, response);
    } finally {

        mdcService.removeAll();
    }
}

Естественно, что приведенный ниже тест не пройден, потому что у меня нет действительного сеанса. Очевидно, что я получаю исключение нулевого указателя всякий раз, когда я вызываю filter.doFilterInternal (request, response, filterChain); . В тестовом классе «mock-session» не настроен и не имеет идентификатора. В моем модульном тесте у меня есть это.

    @RunWith(SpringJUnit4ClassRunner.class)
    @ActiveProfiles(value = {"test"})
    public class AppLoggingFilterUnitTest {

        @Mock
        AppLoggingMDCService mdcService;

        @Mock
        MockHttpServletRequest request;

        @Mock
        MockHttpServletResponse response;

        @Mock
        MockFilterChain filterChain;

        @Mock
        MockHttpSession session; 

        @InjectMocks
        AppLoggingFilter filter;

        @Before
        public void setUp() {
            MockitoAnnotations.initMocks(this);
            request.setSession(session);
        }

        @Test
        public void testCustomerIdHasBeenLogged() throws Exception {
            String customerId = "1234";
            when(request.getHeader(AuthorizationConstants.CUSTOMER_KEY)).thenReturn(customerId);
            filter.doFilterInternal(request, response, filterChain);
            verify(mdcService, times(1)).put(AppLoggingMDCService.LOG_KEY_CUST_ID,customerId);
        }
  }

Итак, возвращаясь к моему вопросу, как имитировать как действительный макет "MockHttpSession", чтобы другие мои тесты не провалились?

ОБНОВЛЕНИЕ Итак, я добавил сессию в свой тестовый класс следующим образом. В моем методе настройки, где я сказал, чтобы вернуть «Mocked» сеанс. Тест проходит только когда я звоню String sessId = request.getSession().getId();. если я попытаюсь сделать DigestUtils.sha256Hex как String sessId = DigestUtils.sha256Hex(request.getSession().getId());, все тесты не пройдут из-за нулевого указателя. Я не уверен почему. Mocking DigestUtils не имеет особого смысла.

@Mock
AppLoggingMDCService mdcService;

@Mock
HttpServletRequest request;

@Mock
HttpServletResponse response;

@Mock
FilterChain filterChain;

@Mock
HttpSession session; 

@InjectMocks
AppLoggingFilter filter;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    when(request.getSession()).thenReturn(this.session);
}

1 Ответ

0 голосов
/ 02 октября 2019

Вы многое делаете в своем тесте, и это сложный путь. Удалите бегуна, удалите Mockito для Mock*, так как те должны быть созданы, а не издеваться.


public class AppLoggingFilterUnitTest {

    @Mock
    private AppLoggingMDCService mdcService;

    @InjectMocks
    private AppLoggingFilter filter;

    private MockHttpServletRequest request;
    private MockHttpServletResponse response = new MockHttpServletResponse();
    private MockFilterChain filterChain = new MockFilterChain();


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        this.request = new MockHttpServletRequest();
        this.request.addHeader(AuthorizationConstants.CUSTOMER_KEY, "1234"); 
    }

    @Test
    public void testCustomerIdHasBeenLogged() throws Exception {
        filter.doFilterInternal(request, response, filterChain);
        verify(mdcService, times(1)).put(AppLoggingMDCService.LOG_KEY_CUST_ID,customerId);
    }
}

Создавая макеты для классов Mock*, вы в основном победили назначение этих классов.

...