模拟InfluxDB客户端来测试MetricCollector类

时间:2017-09-01 10:43:59

标签: java mockito testng influxdb

我有一个在InfluxDB上存储数据的指标收集器,我想测试存储指标的方法。我尝试过,但我无法模仿InfluxDB客户端。我不想在测试环境中指向真正的InfluxDB

到目前为止,我所做的一切都是一些"空指针异常"和连接被拒绝了。

这是我的测试(使用TestNG)。我究竟做错了什么?

    @Test
    public void validateMetrics() {
        String influxHost = "http://localhost";
        String credentials = "admin:admin";
        String influxDatabaseName = "testDataBase";
        influxDB = InfluxDBFactory.connect(influxHost, credentials.split(":")[0], credentials.split(":")[1]);

        MetricsCollector metricsCollector = null;

        try {
            String hostName = "test-server-01";
            int statusValue = 1;
            metricsCollector = new MetricsCollector(influxDB);


            BatchPoints metrics = metricsCollector.initBatchPoint(influxDatabaseName); 
            Point point = metricsCollector.setMetric(hostName, "status", statusValue);
            metrics = metricsCollector.addToMetrics(metrics, point);

            Assert.assertTrue(metrics.getPoints().get(0).lineProtocol().contains(hostName));
            Assert.assertTrue(metrics.getPoints().get(0).lineProtocol().contains("status=" + statusValue));
        } finally {
           if (metricsCollector != null) {
                metricsCollector.closeConnection();
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

我怀疑你无法模仿InfluxDB客户端的原因是它是由静态方法创建的:InfluxDBFactory.connect()。要嘲笑这个,你需要PowerMock

这样的事情:

@PrepareForTest({InfluxDBFactory.class})
public class ATestClass {

    @Test
    public void validateMetrics() {
        // this allows you to mock static methods on InfluxDBFactory
        PowerMockito.mockStatic(InfluxDBFactory.class);

        String influxHost = "http://localhost";
        String credentials = "admin:admin";
        String influxDatabaseName = "testDataBase";

        InfluxDB influxDB = Mockito.mock(InfluxDB.class);

        // when the connect() method is invoked in your test run it will return a mocked InfluxDB rather than a _real_ InfluxDB
        PowerMockito.when(InfluxDBFactory.connect(influxHost, credentials.split(":")[0], credentials.split(":")[1])).thenReturn(influxDB);

        // you won't do this in your test, I've only included it here to show you that InfluxDBFactory.connect() returns the mocked instance of InfluxDB
        InfluxDB actual = InfluxDBFactory.connect(influxHost, credentials.split(":")[0], credentials.split(":")[1]);
        Assert.assertSame(influxDB, actual);

        // the rest of your test
        // ...
    }
} 

注意:TestNG,Mockito和PowerMock对herehere描述了特定的兼容性要求。

答案 1 :(得分:0)

我完全误解了mockito是如何运作的。这是我的固定代码:

    @Mock private InfluxDB influxDB;
    @Test
    public void validateMetrics() {
        MetricsCollector metricsCollector = null;
        String influxHost = "http://localhost";
        String credentials = "admin:admin";
        String influxDatabaseName = "testDataBase";

        influxDB = InfluxDBFactory.connect(influxHost, credentials.split(":")[0], credentials.split(":")[1]);

       try {
            String hostName = "test-server-01";
            int statusValue = 1;
            metricsCollector = new MetricsCollector(influxDB);

            BatchPoints metrics = metricsCollector.initBatchPoint(influxDatabaseName); 
            Point point = metricsCollector.setMetric(hostName, "status", statusValue);
            metrics = metricsCollector.addToMetrics(metrics, point);

            Assert.assertTrue(metrics.getPoints().get(0).lineProtocol().contains(hostName));
            Assert.assertTrue(metrics.getPoints().get(0).lineProtocol().contains("status=" + statusValue));
       } finally {
           if (metricsCollector != null) {
                metricsCollector.closeConnection();
            }
       }
    }
是的,加上那个简单的" mock"注释,一切正常。