2016-06-07 50 views
1

我试图开发一个简单的单元测试来绑定我的机器上的一个端口,测试该端口绑定,然后释放该端口并测试它是释放。目前我使用这种幼稚的做法测试阿卡告诉不使用Thread.sleep

class ServerTest extends FlatSpec with MustMatchers { 
    "Server" must "bind a tcp server to an address on our machine" in { 
    //if this fails this means that the port is in use before our test case is run 
    val port = 18333 
    isBound(port) must be (false) 
    val actor = Server() 
    actor ! Tcp.Bind(actor, new InetSocketAddress(port)) 
    Thread.sleep(1000) 
    isBound(port) must be (true) 
    Thread.sleep(1000) 
    actor ! Tcp.Unbind 
    Thread.sleep(1000) 
    isBound(port) must be (false) 
    } 


    /** 
    * Tests if a specific port number is bound on our machine 
    * @param port 
    * @return 
    */ 
    def isBound(port : Int) : Boolean = { 
    val tryBinding : Try[Unit] = Try { 
     val socket = new java.net.Socket() 
     socket.connect(new java.net.InetSocketAddress(port),1000) 
     socket.close() 
    } 

    tryBinding.isSuccess 
    } 
} 

我想考这个,而无需使用调用Thread.sleep,因为这是一个阻塞调用。任何人都可以提供一个更习惯解决方案吗?

回答

2

当发送TCP.Bind,你应该期待一个答复,说明无论是成功还是失败:http://doc.akka.io/japi/akka/2.3.2/akka/io/Tcp.Bind.html

绑定消息发送到TCP管理员角色,通过TcpExt.manager()获得 以绑定到监听套接字。 管理器使用Tcp.CommandFailed或者处理 的actor响应,listen套接字回复一个Tcp.Bound消息。如果绑定消息中的本地端口 设置为0,则检查Tcp.Bound消息应检查 以查找绑定的实际端口。

您应该使用AkkaTestKit(http://doc.akka.io/docs/akka/snapshot/scala/testing.html),并使用两种ImplicitSenderTestProbe发送TCP.Bind,然后等待答案。

例如:

val probe = TestProbe() 
probe.send(actor, Tcp.Bind(actor, new InetSocketAddress(port))) 
probe.expectMsg(Tcp.Bound) 

测试代码要么继续被接收到应答时,或者,如果不超时(这是在呼叫expectMsg配置)内接收失败。

+0

我试图按照您的测试用例对另一位我在这里的演员进行测试,由于某种原因TestProbe缺少该信息,您能否看看它? https://stackoverflow.com/questions/37706268/testprobe-missing-akka-message –

相关问题