春季3自动装配和junit测试

mik*_*e27 44 junit spring autowired

我的代码:

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

    public void method() {}
}

public interface X {...}

@Component
public class B implements X {
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想在隔离类A中测试.我必须模拟B类吗?如果有,怎么样?因为它是自动装配的,并且没有可以发送模拟对象的setter.

ear*_*las 83

我想在隔离级别A中进行测试.

你应该绝对模拟B,而不是实例化并注入B的实例.重点是测试A是否有效,所以你不应该允许潜在破坏的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
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于模拟getMeaningOfLife()到42 :-). (32认同)
  • 使用新版本的Mockito,我会在`A`的声明中使用`@InjectMocks`注释并摆脱反射`setField(..)` (11认同)

Mik*_*dge 18

以下是我如何使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

FooDAO.java

public class FooDAO {
    public Foo findById(Long id) {
        /* implementation */
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果不使用`MockitoJUnitRunner`,重要的是要记住`FooServiceTest`:`@Before public void initMocks(){MockitoAnnotations.initMocks(this); }` (6认同)

Jef*_*rey 15

您可以使用Spring ReflectionTestUtils.setField(或junit扩展PrivateAccessor)通过反射注入字段,或者您可以创建模拟应用程序上下文并加载它.虽然对于简单的单元(非集成)测试,我赞成使用反射来简化.