1. 程式人生 > >使用GroboUtils多執行緒併發請求測試springmvc controller

使用GroboUtils多執行緒併發請求測試springmvc controller

1. 需求

有一個下載pdf的springmvc controller,希望模擬一下併發訪問的情況,怎麼辦呢?

2. 解決方案

由於是pdf,其http響應為

那麼我們訪問時返回的是二進位制,而不是網頁那種text/html

於是寫一個儲存二進位制檔案的方法

public void saveBinaryFile(URL url) throws IOException {
        URLConnection uc = url.openConnection();
        String contentType = uc.getContentType();
        int contentLength = uc.getContentLength();
        if (contentType.startsWith("text/") || contentLength == -1 ) {
            throw new IOException("This is not a binary file.");
        }
        InputStream raw = uc.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] data = new byte[contentLength];
        int offset = 0;
        while (offset < contentLength) {
            int bytesRead = in.read(data, offset, data.length - offset);
            if (bytesRead == -1) break;
            offset += bytesRead;
        }
        if (offset != contentLength) {
            throw new IOException("Only read " + offset
                    + " bytes; Expected " + contentLength + " bytes");
        }
    String filename = UUID.randomUUID()+".pdf";
    try (FileOutputStream fout = new FileOutputStream(filename)) {
        fout.write(data);
        fout.flush();
    }
}

測試方法

Junit本身是不支援普通的多執行緒測試的,這是因為Junit的底層實現上,是用System.exit退出用例執行的。JVM都終止了,在測試執行緒啟動的其他執行緒自然也無法執行。

使用Junit多執行緒測試的開源的第三方的工具包GroboUtils

pom.xml

<!--springmvc中進行多執行緒測試-->
<dependency>
	<groupId>net.sourceforge.groboutils</groupId>
	<artifactId>groboutils-core</artifactId>
	<version>5</version>
	<scope>system</scope>
	<systemPath>F:/jar_package/groboutils-core-5.jar</systemPath>
</dependency>
測試方法
    @Test
    public void testSaveBinaryFile3() throws IOException {
        TestRunnable runner = new TestRunnable() {
            @Override
            public void runTest() throws Throwable {
                //測試內容
                String urlStr = "http://localhost:8019/xxx”;
                URL url = null;
                try {
                    url = new URL(urlStr);
                    new RenderPdfControllerTest().saveBinaryFile(url);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        //Rnner陣列,相當於併發多少個
        int runnerCount = 5;
        TestRunnable[] trs = new TestRunnable[runnerCount];
        for (int i = 0; i < runnerCount; i++) {
            trs[i] = runner;
        }
        // 用於執行多執行緒測試用例的Runner,將前面定義的單個Runner組成的陣列傳入
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);
        try {
            // 開發併發執行數組裡定義的內容
            mttr.runTestRunnables();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
3. 原理

GroboUtils實現原理是讓測試主執行緒等待所有測試子執行緒執行完成後再退出。想到的辦法是Thread中的join方法。看一下其關鍵的原始碼實現