使用 apache httpclient LocalTestServer 对 webDav 客户端进行集成测试

Integration Test to webDav client using apache httpclient LocalTestServer

我正在尝试使用 apache httpclient LocalTestServer 为 WebDavClient(基于 jackrabbit)编写集成测试。 我受到以下blog的启发,写了下面的测试:

public class WebDAVClientIT {

    private LocalTestServer server;

    @Before
    public void setup() throws Exception{
        server = new LocalTestServer(null, null);
        server.start();
        //direct all requests to my handelr
        server.register("/*", new WebDavHandler());
    }

    @Test
    public void testUploadFileStringInputStreamString() throws Exception {

        WebDAVClient webDavClient = new WebDAVClient();
        //set the client user/pass etc
        webDavClient.init();

        byte[] data = "123,456,789,123,456,789".getBytes();
        InputStream input = new ByteArrayInputStream(data);
        Status uploadFileStatus = webDavClient.uploadFile("test/file.csv", input, "text/csv");
        assertThat(uploadFileStatus.getStatusCode(), is(HttpStatus.SC_CREATED));

    }

    @After
    public void distory() throws Exception {
        server.stop();
    }
}

我创建了一个请求处理程序,使服务器感觉像一个 WebDav 服务器。

public class WebDavHandler implements HttpRequestHandler {
        private Map<String, String> resources;
        public WebDavHandler() {
            //map existing resources 
            resources = new HashMap<>();
        }

        @Override
        public void handle(HttpRequest request, HttpResponse response,
                HttpContext context) throws HttpException, IOException {
            RequestLine requestLine = request.getRequestLine();
            String method = requestLine.getMethod();
            String uri = request.getRequestLine().getUri();

            switch (method) {
            case "GET":
                if (resources.containsKey(uri)) {
                    response.setStatusCode(HttpStatus.SC_OK);
                } else {
                    response.setStatusCode(HttpStatus.SC_NOT_FOUND);
                }
                break;
            case "MKCOL":
                if (resources.containsKey(uri)) {
                    response.setStatusCode(HttpStatus.SC_OK);
                } else {
                    response.setStatusCode(HttpStatus.SC_CREATED);
                    resources.put(uri, uri);
                }
                break;
            }
            logger.info("Executing " + request);
        }

    }

现在我的问题是 LocalTestServer 不是真正的 WebDav 服务器,WebDav 支持的一些方法将不被 LocalTestServer 支持,例如MkCol 方法

[statusCode=501, statusText=Internal Server Error, responseString=MKCOL method not supported]

如何扩展 LocalTestServer 以模拟 webdav 缺少的方法。

您需要注入一个自定义连接工厂,它知道额外的请求方法。

请注意,我使用 HttpClient 4.4 来组合这个示例。

public class TestDAV extends LocalServerTestBase {

    @Before @Override
    public void setUp() throws Exception {
        super.setUp();
        HttpRequestFactory requestFactory = new DefaultHttpRequestFactory() {
            @Override
            public HttpRequest newHttpRequest(final RequestLine requestline) throws MethodNotSupportedException {
                if (requestline.getMethod().equalsIgnoreCase("BLAH")) {
                    return new BasicHttpRequest(requestline);
                }
                return super.newHttpRequest(requestline);
            }
        };
        HttpMessageParserFactory<HttpRequest> requestParserFactory = new DefaultHttpRequestParserFactory(
                BasicLineParser.INSTANCE, requestFactory);
        DefaultBHttpServerConnectionFactory connectionFactory = new DefaultBHttpServerConnectionFactory(
                ConnectionConfig.DEFAULT, requestParserFactory, DefaultHttpResponseWriterFactory.INSTANCE);
        this.serverBootstrap.setConnectionFactory(connectionFactory);
    }

    @Test
    public void testBlah() throws Exception {

        this.serverBootstrap.registerHandler("/stuff", new HttpRequestHandler() {
            @Override
            public void handle(
                    final HttpRequest request,
                    final HttpResponse response,
                    final HttpContext context) throws HttpException, IOException {
                response.setEntity(new StringEntity("Blah", ContentType.TEXT_PLAIN));
            }
        });

        final HttpHost target = start();
        final HttpRequest get = new BasicHttpRequest("BLAH", "/stuff");
        final CloseableHttpResponse response = this.httpclient.execute(target, get);
        try {
            Assert.assertEquals(200, response.getStatusLine().getStatusCode());
            EntityUtils.consume(response.getEntity());
        } finally {
            response.close();
        }
    }

}