2011-12-30 43 views
0

说我有一个模拟的设置是这样的:如何确定JMock模拟对象嘲笑哪个类?

JUnit4Mockery context = new JUnit4Mockery(); 
MyInterface mock = context.mock(MyInterface.class); 

后来我想检查我的模拟对象,找出它的嘲讽什么课:

Class mockedClass = mock.??? //would return MyInterface.class 

我没看到什么明显,JMock的(2.5.1)有关如何做到这一点的javadoc - 为mock方法签名

<T> T mock (Class<T> typeToMock) 

在以前的版本(我看着1.2.0)Y OU将直接创建一个Mock对象,它的方法之一是

Class getMockedType() 

我试图做到的,是使用DI里面我的单元测试的单元测试框架。 (我使用的是Guice 3.0)。在测试中使用DI是对我正在使用的应用程序服务器/平台的限制 - 我测试的对象是具有自己的Injector的多重子类的子类,这就是我试图填充。

我不希望在每个测试创建AbstractModule的匿名实例,所以我试图建立这样的事情(这似乎将在1.2工作过):

public class MockModule extends AbstractModule { 
    private Iterable<Mock> mocks; 

    public MockModule(Iterable<Mock> mocks) { 
     this.mocks = mocks; 
    } 

    protected void configure() { 
     for (Mock mock : mocks) { 
      bind(mock.getMockedType()).toInstance(mock); 
     } 
    } 
} 

唯一缺少的是这个问题的答案(如果有的话)。

响应接受的答案

这里是我结束了创建这个用例:

import java.lang.reflect.Proxy; 
import com.google.common.collect.Lists; 
import com.google.inject.AbstractModule; 

@SuppressWarnings({ "rawtypes", "unchecked" }) 
public class MockModule extends AbstractModule { 
    private final Iterable mocks; 

    public MockModule(Object mock) { 
     mocks = Lists.newArrayList(mock); 
    } 

    public MockModule(Iterable mocks) { 
     this.mocks = mocks; 
    } 

    protected void configure() { 
     for (Object mock : mocks) { 
      Class superclass = mock.getClass().getSuperclass(); 
      if (superclass != Object.class && superclass != Proxy.class) { 
       bind(superclass).toInstance(mock); 
       continue; 
      } 
      Class[] interfaces = mock.getClass().getInterfaces(); 
      if (interfaces.length > 0) { 
       bind(interfaces[0]).toInstance(mock); 
      } 
     } 
    } 
} 

回答

1
Class mockedClass = mock.getClass().getInterfaces()[0]; 
System.out.println("Class is " + mockedClass.getCanonicalName()); 

会打印:

Interface is MyInterface 

有可能更可靠的方式来做到这一点,但它为这个特定的工作做好了准备JMock版本至少。

+0

谢谢!我会拭目以待,看看有人可以提出更强大的版本,但这肯定会让我指出正确的方向。 – arootbeer 2011-12-30 09:17:30

+0

另一种方法可能是创建一个自定义的替代者,为模拟对象添加一个额外的接口来查询他们的类。 – 2011-12-30 09:56:34

+0

我真的很喜欢这个想法......我会研究它。 – arootbeer 2011-12-30 21:09:15

0

我不确定我是否理解你这样做的动机。 JMock通常用于单元测试一个对象或一小群对象,这意味着测试中的所有内容都会被刷新。 DI通常在整合或验收测试的层面上进行测试,在锻炼看起来更像真实组件的东西时。

你在测试中用DI来表现什么?

+0

我正在测试的对象在内部使用Guice'Injector'(这是它们的子类提供的服务)。我*必须*用我的嘲笑填充注射器以便测试它们。我仍然只测试对象的直接依赖关系;只是对象本身不是使用DI创建的,而是为了我们的理智而消费DI。 – arootbeer 2011-12-30 09:22:42

+0

我还没有看到代码,但我的标准回答是,测试正试图告诉你一些有关设计的内容... – 2011-12-30 16:19:35

+0

我完全同意 - 询问我的团队主管我有多少抱怨。但是,这些对象的创建在运行时不受我控制,因此根据我的观点,根本无法获得DI。 – arootbeer 2011-12-30 21:07:19