2012-03-21 2 views
25

Я пытаюсь написать Unit-тест для класса, который имеет несколько полей, отмеченных @Autowired. Учитывая тот факт, что Spring автоматически разрешает конкретные реализации этих полей, мне сложно определить, как подключить мои объекты Mock (созданные через EasyMock) в качестве зависимостей во время тестового запуска. Использование @Autowired в классе означает отсутствие сеттеров в этом классе. Есть ли способ, чтобы я мог подключать свои макетные объекты, не создавая дополнительных разделителей в классе?Узел тестирования класса с автоподзаводом с использованием Junit и EasyMock?

Вот пример того, что я пытаюсь сделать:

public class SomeClassUnderTest implements SomeOtherClass{ 

@Autowired 
private SomeType someType; 

@Autowired 
private SomeOtherType someOtherType; 

@Override 
public SomeReturnType someMethodIWouldLikeToTest(){ 
//Uses someType and someOtherType and returns SomeReturnType 
} 

} 

Вот как я крафта мой класс Test, прежде чем я попал в стену:

public class MyTestClassForSomeClassUnderTest{ 
    private SomeType someType; 
    private SomeOtherType someOtherType; 

    @Before 
    public void testSetUp(){ 
    SomeClassUnderTest someClassToTest = new SomeClassUnderTest(); 
    someType = EasyMock.createMock(SomeType.class); 
    someOtherType = EasyMock.createMock(SomeOtherType.class); 
    //How to set dependencies???? 
    } 

    @Test 
    public void TestSomeMethodIWouldLikeToTest(){ 
    //?????? 
    } 

} 

Это будет здорово, чтобы получить нажмите в правильном направлении.

Благодаря

ответ

34

Вы можете рефлекторно инъекционные зависимости непосредственно в поле, используя ReflectionTestUtils, например,

ReflectionTestUtils.setField(testInstance, "fieldName", fieldValue); 

Некоторые утверждают, что это предпочтительнее, чтобы добавить пакет видимый метод установки к классу так или иначе, используются исключительно тестами. В качестве альтернативы, используйте конструкторы с автосозданием, а не поля с автосогласованием, и вставляйте в них тестовые зависимости.

+0

Спасибо за отзыв. –

+1

http://stackoverflow.com/questions/16426323/injecting-into-autowired-variable-during-testing – Dan

+0

EasyMock поддерживает с версии 3.2 аналогичные аннотации к Mockito для макетирования. См. Мой ответ. – krm

6

Несмотря на то, что эти поля можно настроить с помощью отражения, это не позволит вашим инструментам разработки найти способы использования этих полей и затруднит вам рефакторинг SomeClassToTest в будущем.

Было бы лучше добавить публичные сеттеры для этих полей и разместить вместо них аннотации @Autowired. Это не только позволяет избежать отражения, но также разъясняет внешний интерфейс класса и гарантирует, что ваш модульный тест использует именно этот интерфейс. Я вижу, что SomeClassToTest уже реализует интерфейс SomeOtherClass, и я предполагаю, что клиенты SomeClassToTest используют этот интерфейс, поэтому существует небольшая опасность при создании сеттеров на SomeClassToTest публике.

Еще лучше использовать инжектор конструктора и сделать поля окончательными. Вы по-прежнему можете использовать @Autowired в аргументах конструктора.

1

Я не рекомендую ответ, который был принят, т. Е. Используя отражение самостоятельно (без насмешливой структуры).

Начиная с версии 3.2 EasyMock вы можете использовать аннотации, чтобы определить макеты и ввести их в тестируемый класс. Полное описание, как это сделать, можно найти в официальной документации EasyMock: http://easymock.org/user-guide.html#mocking-annotations

Вот пример из вышеупомянутого сайта:

import static org.easymock.EasyMock.*; 
import org.easymock.EasyMockRunner; 
import org.easymock.TestSubject; 
import org.easymock.Mock; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

@RunWith(EasyMockRunner.class) 
public class ExampleTest { 

    @TestSubject 
    private ClassUnderTest classUnderTest = new ClassUnderTest(); // 2 

    @Mock 
    private Collaborator mock; // 1 

    @Test 
    public void testRemoveNonExistingDocument() { 
    replay(mock); 
    classUnderTest.removeDocument("Does not exist"); 
    } 
} 
Смежные вопросы