简体   繁体   中英

Mocking extended java classes in groovy

How can I mock java classes extended by groovy (Input/Output Stream) in groovy test? I tried mockito and groovy mocks but with no luck. Is there any way it can work? Any java/groovy library that can handle this case?

There is a groovy servlet below that uses groovy getText method on InputStream and setBytes on OutputStream. How to mock (1) getText and verify (2) setBytes in groovy test?

Thanks for help,

Michal

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

@groovy.transform.TypeChecked
class SomeServlet extends javax.servlet.http.HttpServlet {

    @Override
    protected void doPost(final HttpServletRequest request, final HttpServletResponse response) {
        final String charset = request.getCharacterEncoding();
        final String requestPayload = request.getInputStream().getText(charset); // GROOVY getText
        response.setContentType(request.getContentType());
        response.setStatus(200);
        response.setCharacterEncoding(charset);
        response.getOutputStream().setBytes(requestPayload.getBytes(charset)) // GROOVY setBytes
    }
}


class SomeServletTest {
    @org.testng.annotations.Test
    void aTest() {
        // given
        HttpServletRequest request = mock(HttpServletRequest)
        when(request.getCharacterEncoding()).thenReturn("UTF-8")
        when(request.getInputStream().getText("UTF-8")).thenReturn("some text")  // (1)

        HttpServletResponse response = mock(HttpServletResponse)

        def ss = new SomeServlet()

        // when
        ss.doPost(request, request)

        // then
        verify(response.getOutputStream()).setBytes("some text") // (2)
    }
}

I suggest you use ready made mocks of HttpServletRequest and HttpServletResponse instead of mocking the classes yourself. Mocking Servlet API classes is difficult and would prove too costly in real world scenarios.

Spring Framework has it all: http://docs.spring.io/spring-framework/docs/3.2.x/javadoc-api/org/springframework/mock/web/package-summary.html

Using MockHttpServletRequest and MockHttpServletResponse classes, the unit test would be very simple and readable:

import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.mock.web.MockHttpServletResponse
import org.testng.Assert
import org.testng.annotations.Test

class SomeServletTest {

    @Test
    void aTest() {
        def request = new MockHttpServletRequest(
                characterEncoding: "UTF-8",
                content: "some text".bytes)

        def response = new MockHttpServletResponse()

        def ss = new SomeServlet()
        ss.doPost(request, response)

        Assert.assertEquals(response.getContentAsString(), "some text")
    }
}

Even if you don't want to build your whole application using Spring Framework, you can still benefit from its excellent unit test support.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM