2017-06-09 64 views
1

我想單元測試一個來自vertx WebClient的http調用VertxUnitRunner和RXified版本的vertx。單元測試Vertx - java.util.concurrent.TimeoutException

問題是我的單元測試總是失敗,出現超時異常。有沒有不同的方式單元測試WebClient http調用?下面是我的代碼:

import io.vertx.core.AsyncResult; 
import io.vertx.core.http.HttpClientOptions; 
import io.vertx.core.http.HttpServerOptions; 
import io.vertx.ext.unit.TestContext; 
import io.vertx.ext.unit.junit.VertxUnitRunner; 
import io.vertx.rxjava.core.Vertx; 
import io.vertx.rxjava.core.buffer.Buffer; 
import io.vertx.rxjava.core.http.HttpServer; 
import io.vertx.rxjava.ext.web.client.HttpResponse; 
import io.vertx.rxjava.ext.web.client.WebClient; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import rx.Single; 


@RunWith(VertxUnitRunner.class) 
public class MyVertxTest { 

    private Vertx vertx; 
    private WebClient client; 

    @Before 
    public void setUp() throws Exception { 
     vertx = Vertx.vertx(); 
    } 

    @Test 
    public void testGetContactDetails(TestContext context) { 

     System.out.println("start"); 
     long start = System.currentTimeMillis(); 
     HttpServer server = vertx.createHttpServer(new HttpServerOptions().setPort(TEST_SERVER_PORT)); 

     server.requestStream().handler(req -> { 
      req.response().setChunked(true).write("foo bar").end(); 
     }); 

     System.out.println("created server"); 

     try { 
      server.listen(9000, "localhost", (AsyncResult<HttpServer> ar) -> { 

       client = WebClient.wrap(vertx.createHttpClient(new HttpClientOptions())); 

       System.out.println("created client"); 

       Single<HttpResponse<Buffer>> single = client 
         .get(9000, "localhost", "/foo") 
         .rxSend(); 

       single.subscribe(s -> { 
        System.out.println("inside subscribe"); 
        context.assertEquals("foo bar", s.bodyAsString()); 
       }, e -> { 
        context.fail(e); 
       }); 
      }); 

      context.async().await(); 
      System.out.println("total time : " + (System.currentTimeMillis() - start/1000)+" seconds); 

     } catch (Exception e) { 
      context.fail(e); 
     } finally { 
      server.close(); 
     } 
    } 
} 

的測試總是失敗,由於到120秒

輸出

start 
created server 
created client 
inside subscribe 
total time : 120 

java.util.concurrent.TimeoutException 
    at io.vertx.ext.unit.impl.TestContextImpl$Step.lambda$run$0(TestContextImpl.java:112) 
    at java.lang.Thread.run(Thread.java:745) 

回答

3

由於async你使用的是錯誤的之後超時。它類似於java CountDownLatch。它在docs

所以正確使用描述應該是:

 Async async = context.async(); //here 

     server.listen(9000, "localhost", (AsyncResult<HttpServer> ar) -> { 

      client = WebClient.wrap(vertx.createHttpClient(new HttpClientOptions())); 

      System.out.println("created client"); 

      Single<HttpResponse<Buffer>> single = client 
       .get(9000, "localhost", "/foo") 
       .rxSend().subscribeOn(Schedulers.io()); 

      single.subscribe(s -> { 
       System.out.println("inside subscribe"); 
       context.assertEquals("foo bar", s.bodyAsString()); 
       async.complete(); //here 
      }, e -> { 
       context.fail(e); 
      }); 
     }); 

     async.awaitSuccess(); 

你也可以讓你的代碼阻止,以避免異步測試:

 Single<HttpServer> obs = server.rxListen(9000, "localhost"); 
     obs.toBlocking().value(); //here 

     client = WebClient.wrap(vertx.createHttpClient(new HttpClientOptions())); 

     System.out.println("created client"); 

     Single<HttpResponse<Buffer>> single = client 
      .get(9000, "localhost", "/foo") 
      .rxSend().subscribeOn(Schedulers.io()); 

     Assert.assertEquals(single.toBlocking().value().bodyAsString(), "foo bar"); //here 
+0

非常感謝! – Rakesh

0

你可以嘗試添加超時規則

@規則

public Timeout timeoutRule = Timeout.seconds(3600);