问候。
我正在嘲笑一个搜索引擎,用于在我的网络应用中进行测试。此搜索引擎返回具有不同模式的xml文档。架构取决于称为集合集的参数。基于集合集返回不同的模式是难以模拟的部分,因为指定集合集基本上是一种设置方法,并且在此处是空的。此搜索引擎是外部jar文件,因此我无法修改API。我必须处理所提供的内容。这是一个例子:
Engine engine = factory.getEngine();
Search search = engine.getSearch();
search.addCollectionSet(someCollectionSet);
SearchResult result = search.getSearchResult();
Document[] documents = result.getAllDocuments();
然后对于每个文档,我可以通过调用
来获取xmldocument.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)
,这样当它被调用时,我可以做一些关闭参数并确保使用不同的生成器。有谁知道我怎么能做到这样的事情?或者是否有某种形式的依赖注入可用于有条件地连接我的生成器?
谢谢!
更新
我已经更改了我的工厂对象,因此它永远不会返回引擎,而是从该引擎中搜索和查找对象,所以现在我可以这样做:
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将根据参数返回不同的值。似乎必须有一种方法可以做到这一点,我只是没有足够的经验与Mockito想出来。但肯定有人这样做了!
答案 0 :(得分: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");