Подтвердить что ты не робот

Spring 3 автоувеличивание и тестирование юнита

Мой код:

@Component
public class A {
    @Autowired
    private B b;

    public void method() {}
}

public interface X {...}

@Component
public class B implements X {
    ...
}

Я хочу протестировать в классе изоляции A. Должен ли я высмеивать класс B? Если да, то как? Потому что он автообновлен, и нет сеттера, где я мог бы отправить насмешливый объект.

4b9b3361

Ответ 1

Я хочу протестировать в классе изоляции A.

Вы должны абсолютно издеваться над B, а не создавать экземпляр и вводить экземпляр B. Цель состоит в том, чтобы проверить A, работает ли B, поэтому вы не должны допускать, чтобы потенциально поврежденный B мешал тестированию A.

Тем не менее, я настоятельно рекомендую Mockito. Как издевательские рамки идут, он чрезвычайно прост в использовании. Вы должны написать что-то вроде следующего:

@Test
public void testA() {
    A a = new A();
    B b = Mockito.mock(B.class); // create a mock of B
    Mockito.when(b.getMeaningOfLife()).thenReturn(42); // define mocked behavior of b
    ReflectionTestUtils.setField(a, "b", b); // inject b into the B attribute of A

    a.method();

    // call whatever asserts you need here
}

Ответ 2

Вот пример того, как мои тесты работают с Spring 3.1, JUnit 4.7 и Mockito 1.9:

FooService.java

public class FooService {
    @Autowired private FooDAO fooDAO;
    public Foo find(Long id) {
        return fooDAO.findById(id);
    }
}

FooDAO.java

public class FooDAO {
    public Foo findById(Long id) {
        /* implementation */
    }
}

FooServiceTest.java

@RunWith(MockitoJUnitRunner.class)
public class FooServiceTest {
    @Mock private FooDAO mockFooDAO;
    @InjectMocks private FooService fooService = new FooService();

    @Test public final void findAll() {
        Foo foo = new Foo(1L);
        when(mockFooDAO.findById(foo.getId()).thenReturn(foo);

        Foo found = fooService.findById(foo.getId());
        assertEquals(foo, found);
    }
}

Ответ 3

Вы можете ввести поле через отражение, используя Spring ReflectionTestUtils.setField (или расширение junit PrivateAccessor), или вы можете создать контекст прикладного приложения и загрузить его. Хотя для простого теста (неинтеграции) я предпочитаю использовать отражение для простоты.

Ответ 4

Это обсуждение форума имеет смысл для меня. Вы можете объявить своего частного члена b как тип интерфейсаB, который реализуется классом B (т.е. Сервисно-ориентированным), а затем объявить класс MockB, который также реализует тот же интерфейс. В контексте приложения тестовой среды вы объявляете класс MockB и контекст вашего производственного приложения, который вы объявляете обычным классом B, и в любом случае код для класса A не нужно изменять, поскольку он будет автоматически подключен.