我正在尝试开发一个简单的单元测试来绑定我的机器上的端口,测试端口是否绑定,然后释放端口并测试它是否正在释放。目前我正在使用这种天真的方法
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
调用的情况下对此进行测试,因为这是一个阻塞调用。任何人都可以为我提供一个更惯用的解决方案吗?
答案 0 :(得分:2)
发送TCP.Bind
时,您应该会收到一条成功或失败的回复:http://doc.akka.io/japi/akka/2.3.2/akka/io/Tcp.Bind.html
将绑定消息发送到获取的TCP管理器actor 通过TcpExt.manager()来绑定到侦听套接字。该 管理器使用Tcp.CommandFailed或actor处理来回复 listen套接字用Tcp.Bound消息回复。如果是本地端口 在绑定消息中设置为0,然后应该是Tcp.Bound消息 检查找到了绑定的实际端口。
您应该使用AkkaTestKit(http://doc.akka.io/docs/akka/snapshot/scala/testing.html)并使用ImplicitSender
或TestProbe
发送TCP.Bind
,然后等待答案。
例如:
val probe = TestProbe()
probe.send(actor, Tcp.Bind(actor, new InetSocketAddress(port)))
probe.expectMsg(Tcp.Bound)
您的测试代码将在收到回复时继续,或者如果未在超时内收到(在expectMsg
调用中可配置),则会失败。
答案 1 :(得分:1)
您可以使用
within (1000 millisends) {
...
}