2014-11-24 226 views
0

我正在使用mockito并用java6和spring进行开发。mockito:通过反射参数模拟方法调用

我正在为某些开发人员开发测试API,并提出了一些方法来模拟对象和方法(这是一种遗留代码...)。 现在,我想用mockito替换所有这些东西,但我总是提出一个测试API。所以,我开发了一些使用mockito的方法。

我有一个旧的方法有两个参数(字符串)。第一个参数是一个模拟的服务id及其带参数的方法。第二个参数是返回的Object。 例子:

mockReturnObject("myServiceId.myMethod(String, Integer)", myReturnedObject); 

现在,我想用模拟,当和thenReturn方法的Mockito,而且我也不怎么看......也许与 反射而是“何时”的方法是不可能的,因为需要的Mockito的有效的方法。 我该怎么做?谢谢。

+0

我不明白为什么你不能直接在“真正的东西”上使用mockito?你想嘲笑“final”的类(或任何方法)吗? – fge 2014-11-24 16:49:52

+0

你问如何解析“myServiceId.myMethod(String,Integer)”?如果是这样,恐怕这是不可能的。 – 2014-11-24 17:06:40

+1

我认为能够有一个更具体的例子说明你在这里测试什么。完整的测试方法,完整的场景或不适用。这是嘲笑一个家庭嘲笑框架? – macias 2014-11-24 20:12:36

回答

3

这是一个糟糕的主意:您正在尝试重新实现Mockito已经提供的一些系统,同时Mockito提供了许多功能,例如。但是,有一种方法可以完成这项工作,但有一些困难。关键是编写一个custom Answer,使其成为模拟的default answer,然后使用InvocationOnMock比较您的对象,方法名称和方法参数类型。

public class ReflectiveMockAnswer implements Answer<Object> { 
    @Override public Object answer(InvocationOnMock invocation) { 
    // Assume you've successfully parsed each String into a StubbedResponse, with 
    // Object target, String method, String[] argTypes, and Object returnValue. 
    // A Set would beat a for-loop here, should you need to optimize. 
    for (StubbedResponse stubbedResponse : allStubbedResponses) { 
     if (stubbedResponse.target == invocation.getMock() 
      && stubbedResponse.method.equals(invocation.getMethod().getName()) 
      && stringArraysEqual(stubbedResponse.argTypes, 
       typeNamesFrom(invocation.getMethod().getParameterTypes())) { 
     return stubbedResponse.returnValue; 
     } 
    } 
    throw new RuntimeException("Unstubbed method called."); 
    } 
} 

// Later... 
Object yourMockObject = Mockito.mock(classToMock, new ReflectiveMockAnswer()); 

在这一点上,你已经实现的Mockito 的简化版本中,并基于完整版本的的Mockito。您还需要:

  • 解析字符串转换成StubbedResponse,可能与正则表达式
  • 按名称
  • 识别您豆下测试领域拥有的一个模拟替换场适当的类,创建如上,豆在测试前有机会与它

互动......并承认,该解决方案不处理:

  • 验证
  • 任何类的说法匹配,包括基本的 “等于”,在参数类型匹配
  • 名称冲突(com.foo.SomeClass VS com.bar.SomeClass)
  • 重复调用(thenReturn(1, 2, 3).thenThrow(new RuntimeException())

...和不能手柄:

  • 代码搜索工具:你只能告诉哪些方法嘲笑比其他通过搜索字符串,不象在Eclipse中“查找引用”的方式的Mockito可以
  • 编译期工具实时检查和自动化重构工具:如果字段名称,方法名称或参数发生更改,您的测试将在运行时中断;它的Mockito不会有这个问题
  • Final方法:可以的Mockito没有,所以你也不能

除非这是一个“稻草人”或非常临时的解决方案,我强烈建议刚引进的Mockito直接进入你的测试用例,一次一个测试。

相关问题