有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用Mockito为存根方法键入参数

你好

我在模仿搜索引擎在我的web应用程序中进行测试。此搜索引擎返回具有不同模式的xml文档。架构依赖于称为集合集的参数。基于集合集返回不同的模式是很难模拟的部分,因为指定集合集基本上是一种设置方法,而且是一种无效的方法。这个搜索引擎是一个外部jar文件,所以我不能修改API。我必须和他们一起工作。下面是一个例子:

Engine engine = factory.getEngine();
Search search = engine.getSearch();
search.addCollectionSet(someCollectionSet);
SearchResult result = search.getSearchResult();
Document[] documents = result.getAllDocuments();

然后,对于每个文档,我可以通过调用以下命令获取xml:

document.getDocumentText();

当我使用模拟对象时,getDocumentText()返回一个由生成器创建的符合模式的xml字符串。我想做的是使用不同类型的生成器,具体取决于上面第一个代码段的步骤3中提供的集合集。我一直在尝试这样做:

    doAnswer(new Answer() {
        Object answer(InvocationOnMock invocation) {
            if (args == "foo") {
                SearchResult result = getMockSearchResult();
                when(search.getSearchResult()).thenReturn(result);
            }
        }
    }).when(search.addCollectionSet(anyString()));

但这会导致大量的红色高亮显示:)

基本上,我的目标是关闭addCollectionSet(someCollectionSet),这样在调用它时,我可以对参数进行某种关闭,并确保使用不同的生成器。有人知道我怎样才能做到这一点吗?或者是否有某种形式的依赖注入可以用来有条件地连接我的生成器

谢谢

更新

我已经更改了我的factory对象,因此它不会返回引擎,而是从该引擎中搜索和查找对象,因此现在我可以执行以下操作:

Search search = factory.getSearch(collectionSet);

所以我想做的是这样的:

when(factory.getSearch(anyString()).thenAnswer(new Answer() {
    Object answer(InvocationOnMock invocation) {
        switch(args[0]) {
            case fooSet: return fooSearch; break;
            case barSet: return barSearch; break;   

换句话说,我仍然希望在switch语句中关闭传递给getSearch的字符串。诚然,我可以做一些更像felix在下面建议的事情,但我更愿意把我所有的箱子都包在一个开关里。有人能举例说明如何做到这一点吗?谢谢

更新

我已经看到,您可以捕获传递到模拟调用中的参数,但是这些捕获的参数将用于以后的断言。我还没有找到一种方法可以关闭这些参数,这样对mock的调用将根据参数返回不同的值。似乎必须有办法做到这一点,我只是没有足够的经验与莫基托明白这一点。但肯定有人会的


共 (1) 个答案

  1. # 1 楼答案

    我建议将对遗留代码的调用包装到您自己的对象中。 因此,您最终会按照以下思路使用自己的方法:

    class SearchEngineWrapper {
      public String getSearchResult(String collection){
        Engine engine = factory.getEngine();
        Search search = engine.getSearch();
        search.addCollectionSet(someCollectionSet);
        SearchResult result = search.getSearchResult();
        ...
        return document.getDocumentText();
      }
    }
    

    现在您可以模拟这种方法。该方法还很好地记录了您的意图。您还可以在集成测试中测试实际实现

    when(searchEngineWrapper.getSearchResult("abc").thenReturn("foo");
    when(searchEngineWrapper.getSearchResult("xyz").thenReturn("bar");