概述
使用curator framework框架去操作zookeeper时,我们知道因其的方法风格是那种流式的编写风格,所以我们在写单元测试的时候要把链接zookeeper的操作给mock掉,那么着实是不太好写单测。不过好在curator framework有一个专门用于测试的模块,可以让我们在单测运行之前就在本地启动一个zookeeper server实例,以便于让单测可以直接连接本地的zookeeper实例创建curator client,便于做单元测试。
实现
引入依赖
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-test</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
</dependency>
启动zookeeper
private static TestingServer zkServer;
@BeforeClass
public static void startZkServer() throws Exception {
zkServer = new TestingServer(true);
zkServer.start();
}
创建curator framework client
private CuratorFramework zkClient;
@BeforeAll
public CuratorFramework createCuratorClient() {
zkClient = CuratorFrameworkFactory.builder()
//本地启动的zookeeper实例端口,跑单测用
.connectString(zkServer.getConnectString())
.retryPolicy(new RetryNTimes(5, 1000))
.connectionTimeoutMs(40 * 1000)
.sessionTimeoutMs(5 * 1000).build();
zkClient.start();
}
单元测试-创建临时节点
@Test
public void test_createEphemeral() {
String path = "/zk/test";
createEphemeral(path);
List<String> childrens = getChildren("/zk");
Assert.assertEquals(1, childrens.size());
}
private void createEphemeral(String path) {
try {
zkClient.create().withMode(CreateMode.EPHEMERAL).forPath(path);
} catch (NodeExistsException e) {
logger.warn("ZNode " + path + " already exists.", e);
throw new IllegalStateException(e.getMessage(), e);
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
private List<String> getChildren(String path) {
try {
return zkClient.getChildren().forPath(path);
} catch (NoNodeException e) {
return new ArrayList<>();
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
单测完毕后关闭zookeeper server
@AfterClass
public static void closeZkServer() throws IOException {
zkServer.close();
}