2011-12-30 2 views
0

Скажем, у меня есть макет установки, как это:Как определить класс, издевательский объект JMock издевается?

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

А потом я хочу, чтобы изучить мой фиктивный объект, чтобы выяснить, к какому классу он насмешливо:

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

Я ничего не видел очевидно, в JMock (2.5.1) Javadocs о том, как сделать это - подпись для метода mock является

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

в предыдущих версиях (я смотрел на 1.2.0) у НУ бы создать 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); 
     } 
    } 
} 

Единственное, чего не хватает, - это ответ (если таковой есть) на этот вопрос.

ОТВЕТ НА ACCEPTED ОТВЕТА

Вот что я в конечном итоге создание для этого случая использования:

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

+0

Другим подходом может быть создание пользовательского Imposteriser, который добавляет дополнительный интерфейс к макетным объектам для запроса своего класса. –

+0

Мне очень нравится эта идея ... Я рассмотрю ее. – arootbeer

0

Я не уверен, что понимаю ваши мотивы для этого. JMock обычно используется для модуляции теста объекта или небольшого кластера объектов, что означает, что все новое в тесте. DI обычно срабатывает на уровне интеграции или приемочного тестирования, при осуществлении чего-то, что больше похоже на реальный компонент.

Что вы пытаетесь показать, используя DI внутри тестов?

+0

Объекты, которые я тестирую, используют внутреннее средство Guice 'Injector' (это сервис, предоставляемый их подклассом). Я * должен * заполнить инжектор моими макетами, чтобы проверить их. Я все еще проверяю только прямые зависимости объектов; это просто, что сами объекты не создаются с помощью DI, а скорее потребляют DI для нашего здравомыслия. – arootbeer

+0

Я не видел код, но мой стандартный ответ в том, что тесты пытаются рассказать вам что-то о дизайне ... –

+0

Я полностью согласен - спросите мою команду, сколько я жалуюсь. Тем не менее, создание этих объектов вне моего контроля во время выполнения, так что это просто победа, на мой взгляд. – arootbeer