【问题标题】:How to test java code that uses Basho's riak-java-client?如何测试使用 Basho 的 riak-java-client 的 java 代码?
【发布时间】:2015-02-12 21:44:10
【问题描述】:

我正在创建一个小型 Java 服务,它根据所选地点返回餐厅列表。 使用 com.basho.riak:riak-client:2.0.0 从 Riak 检索数据,读取操作包含在 TenacityCommand 中。

下面描述了重要的类,如果您能帮助我创建一个可靠且简单的单元测试,我会很高兴。

命令是使用工厂创建的:

package service.command.factory;

import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.core.query.Location;
import com.basho.riak.client.core.query.Namespace;

import domain.Place;
import service.command.FetchRestaurantsCommand;

public class FetchRestaurantsCommandFactory {

    private final RiakClient riakClient;
    private final Namespace namespace;

    public FetchRestaurantsCommandFactory(final RiakClient riakClient, final Namespace namespace) {
        this.riakClient = riakClient;
        this.namespace = namespace;
    }

    public FetchRestaurantsCommand create(final Place place) {
        Location location = new Location(namespace, place.getName());
        FetchValue riakCommand = new FetchValue.Builder(location).build();
        return new FetchRestaurantsCommand(riakClient, riakCommand);
    }
}

命令如下:

package service.command;

import java.util.Optional;

import service.command.keys.WhereToEatDependencyKeys;

import com.basho.riak.client.api.RiakClient;
import com.basho.riak.client.api.commands.kv.FetchValue;
import com.basho.riak.client.api.commands.kv.FetchValue.Response;
import com.yammer.tenacity.core.TenacityCommand;

import domain.Restaurant;
import domain.RestaurantList;

public class FetchRestaurantsCommand extends TenacityCommand<Optional<RestaurantList>>{

    private final RiakClient riakClient;
    private final FetchValue fetchValue; 

    public FetchRestaurantsCommand(RiakClient riakClient, FetchValue fetchValue) {
        super(WhereToEatDependencyKeys.RIAK_GET_RESTAURANTS);
        this.fetchValue = fetchValue;
        this.riakClient = riakClient;
    }

    @Override
    protected Optional<RestaurantList> run() throws Exception {
        Response response = riakClient.execute(fetchValue);
        return Optional.ofNullable(response.getValue(RestaurantList.class));
    }

    @Override
    protected Optional<RestaurantList> getFallback() {
        return Optional.of(RestaurantList.createFallback(new Restaurant("My failure suggestion")));
    }

}

以上类的用法如下:

Place place = // Created from url parameter
RiakClient riakClient = // created on start using the app's conf
Namespace namespace = // created on start using the app's conf

FetchRestaurantsCommandFactory factory = new FetchRestaurantsCommandFactory(riakClient, namespace);
FetchRestaurantsCommand command = factory.create(place);
return command.execute();

除了TenacityCommand提供的功能外,我应该如何断言我的系统按预期获取数据?

我最初的想法是模拟RiakClient 以返回预定义的FetchValue.Response,然后对生成的RestaurantList 进行断言。 不幸的是,由于其设计,它不可能实例化或Mockito.mockFetchValue.Response

How to mock riak java client? 中接受的答案描述了 Mockito 不起作用的原因。

【问题讨论】:

标签: java unit-testing riak


【解决方案1】:

据我了解,您想编写单元测试。所以你想测试假设一些Response Optional&lt;RestaurantList&gt; 实例是否构造正确。 我能想到的是将riakClient.execute(fetchValue); 包装在一个受保护(或包私有)的辅助函数中,例如:

Response fetch() {
  return riakClient.execute(fetchValue);
}

然后在您的测试中,您可以从FetchRestaurantsCommand 继承并通过返回任何Response 覆盖fetch 函数

现在,您可以编写任何测试来查看给定的ResponseOptional&lt;RestaurantList&gt; 的转换是否符合预期。

如果您需要完整的代码而我的解释不够清楚,请告诉我提供。

【讨论】:

  • 问题是无法实例化 Response 对象。覆盖 fetch() 的类无法创建它的返回值。如果我理解正确,如果是难以创建的 FetchValue,您的解决方案将完美运行。
【解决方案2】:

我最终按照@gontard 的建议使用了 PowerMock。在 GitHub 上查看我的单元测试:FetchRestaurantsCommandTest.java

我考虑在 com.basho.riak.client 包中创建一个假的/模拟的 RiakClient。这样的类有望以与真实客户端相同的方式实例化 Response 对象。它可能适用于 fetchValue,但当涉及更高级的 Riak 概念 s.a. 时它会变得太大。兄弟姐妹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多