鉴于遗留应用程序有1500个spring.xmls。我想为服务编写单元测试。我深深陷入了依赖地狱。我必须按原样接受应用程序,没有出路。
所以我们使用spring-3.something和mockito-1.9,我想要测试服务的好方法。较新的代码大量使用@Autowired注释。
间接地,该服务使用我实际想要在测试中使用的~25个助手(工厂方法等),以及我对此测试不感兴趣的~25个对象。
我目前尝试按上述方式设置上下文,但我对@Mock,@ InjectMocks,@ Autowired的效果感到困惑。
我的测试如下。我需要帮助才能正确设置。
问题:
这是我的样本:
@ContextConfiguration(locations = {
"classpath:/some/path/MainTestConfig.spring.xml"
})
@RunWith(SpringJUnit4ClassRunner.class)
public class SampleTest {
// *** Uninteresting Dependencies to be mocked *** //
@Mock Mock1 mock1;
@Mock Mock2 mock2;
/** Service under test */
@Autowired
SomeService service;
// *** Tightly coupled helpers to be used *** //
@Autowired Helper1 helper1
@Autowired Helper2 helpr2
@Before
public void setup() {
MockitoAnnotations.initMocks(SampleTest.class);
}
@Test
public void testSample() {
// prepare dummy context
SomeContext context = new Context();
// define expected result
int expectedValue = 42;
//execute method under test, record result
Result actualResult = service.execute(context);
//make assertions on result
assertTrue(actualResult.getSomething()==expectedValue);
}
}
答案 0 :(得分:4)
我想将此作为单独的答案发布,因为这应该更好地解决有关@ Mock,@ Autowired和@InjectMocks的实际问题。
@Mock
:这标记了一个字段,应该在调用mock(MyClass.class)
时创建为模拟(使用MockitoAnnotations.initMocks(this)
)。
@Autowired
:标记一个应由Spring分配的字段,该字段使用实现类/接口的bean。
@InjectMocks
:在调用MockitoAnnoations.initMocks(this)
时标记应由Mockito创建的字段。它创建了一个类的实例,并将@Mock
- 带注释的字段注入此实例。 (见评论中对本声明的更正)。
分析:
@InjectMocks
与Spring上下文和@Autowired
不兼容,因为InjectMock
创建了一个不使用Spring实例的类的新实例。
要执行您要查找的内容,您需要使用Springockito。 (延迟更新)Springockito将允许您将模拟注入Spring上下文,从而将这些模拟用作Autowired
候选项。它允许模拟和间谍。在测试中的同一个字段上使用ReplaceWithMock
和Autowired
是一般做法(如wiki上的示例所示)。
答案 1 :(得分:2)
第一个问题,你需要加载spring上下文做这个测试吗?通常,当我有Spring项目时,每个类都有一个UNIT测试,它不会加载上下文文件。我将有一个不同的CONTEXT测试加载上下文文件并验证它是否正确加载。如果您正在进行真正的单元测试,我建议不要加载上下文。如果使用@Autowired
进行测试的类来分配依赖项(因此没有setter),请使用Spring ReflectionTestUtils
来分配这些字段。