假设遗留应用程序有 1500 个 spring.xml。我想为服务编写单元测试。我深陷依赖 hell 。我必须按原样接受应用程序,没有出路。
所以我们使用 spring-3.something 和 mockito-1.9,我想要测试服务的好方法。较新的代码大量使用 @Autowired 注释。
间接地,该服务使用了大约 25 个我实际上想在测试中使用的助手(工厂方法等),以及大约 25 个我对此测试不感兴趣的对象。
我目前尝试以上述方式设置上下文,但我对@Mock、@InjectMocks、@Autowired 的效果感到困惑。
我的测试如下。我需要帮助才能正确设置它。
问题:
- @InjectMocks 的实际效果是什么?
- 我如何(从技术上)决定哪些 Autowiring 的 bean 被真正使用,哪些被模拟替换?
- 我知道,我滥用模拟来制造假货。有没有更简单的方法在单行中获取假货?
- *请注意,我想了解这一点,因为我有大量此类服务...*
这是我的示例:
@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);
}
}
最佳答案
我想将其作为单独的答案发布,因为这应该更好地解决您关于@Mock、@Autowired 和@InjectMocks 的实际问题。
@Mock
:当MockitoAnnotations.initMocks(this)
被调用。
@Autowired
:标记应由 Spring 使用实现类/接口(interface)的 bean 分配的字段。
@InjectMocks
:标记在调用 MockitoAnnoations.initMocks(this)
时应由 Mockito 创建的字段。它创建该类的一个实例并将 @Mock
注释的字段注入(inject)到该实例中。 (请参阅评论中对此声明的更正)。
分析:
@InjectMocks
与 Spring 上下文和 @Autowired
不兼容,因为 InjectMock
创建了它不使用 Spring 的类的新实例实例。
要执行您要查找的操作,您需要使用 Springockito . (延迟更新)Springockito 将允许您将模拟注入(inject)到您的 Spring 上下文中,从而将这些模拟用作 Autowired
候选对象。它允许模拟和 spy 。在测试的同一字段上使用 ReplaceWithMock
和 Autowired
是一般做法(如 wiki 上的示例所示)。
关于spring - 在纠缠的 spring 上下文中进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16013077/