问题描述
假设我有一个类(OrchestratingClass),该类的方法orchestrate()
调用了其他一些较小的其他类的方法(classA的do1()
方法,classB的do2 do2()
方法)。
我想测试的行为orchestrate()
被嘲讽的回应do1()
和do2()
有不同的排列。
我正在使用类似以下内容进行测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public OrchestratingClassTest {
@Inject
private OrchestratingClass oc;
@Test
public void test1() {
// I would like to mock classA's do1() method to send back "1"
// I would like to mock classB's do2() method to send back "2"
}
@Test
public void test2() {
// I would like to mock classA's do1() method to send back "100"
// I would like to mock classB's do2() method to send back "200"
}
static class SimpleConfig {
@Bean
public InterfaceA interfaceA() {
return new ClassA();
}
@Bean
public InterfaceB interfaceB() {
return new ClassB();
}
@Bean
public OrchestratingClass orchestratingClass() {
return new OrchestratingClass();
}
}
}
而且orchestratingClass本身是非常基本的,但是我添加了一些示例代码来辅助可视化:
@Named
public OrchestratingClass {
@Inject
private InterfaceA interfaceA;
@Inject
private InterfaceB interfaceB;
public String orchestrate() {
return interfaceA.do1() + " " + interfaceB.do2();
}
}
现在,我知道可以调整SimpleConfig
类以具有模拟的classA和classB版本,但是随后我被锁定在1个特定的模拟中,并且当我移至test2()时无法“重新模拟”事物。
我坚信,如果我们尝试以“每次测试”方式注入不同的“风味”豆类,则无法为1个单个测试类使用Java配置文件。
是否有人对我的操作有任何建议,以确保我确实在不受到侵害的情况下进行了彻底的测试(例如:为orchestratingClass中的特定类添加了多余的“ setter”,从而避免了注入bean的痛苦)?
本质上,我希望通过应用各种模拟在每次测试的基础上“篡改”特定感兴趣的bean的applicationContext(以及必要的必要的内部管理)。
1楼
这是一个使用Mockito的简单示例:
public class OrchestratingClassTest {
@Mock
private ClassA mockA;
@Mock
private ClassB mockB;
@InjectMocks
private OrchestratingClass oc;
@Before
public void prepare() {
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldConcatenate() {
when(mockA.do1()).thenReturn("1");
when(mockB.do2()).thenReturn("2");
assertEquals("1 2", oc.orchestrate());
}
}
魔术发生在对MockitoAnnotations.initMocks(this)
的调用中,该调用将为使用@Mock
注释的字段创建模拟实例,然后通过@InjectMocks
创建一个Orchestrating类的真实实例并注入其字段。
请注意,即使没有这种魔力,您也可以通过添加一个将ClassA和ClassB作为参数的构造函数作为OrchestratingClass来使您的类易于测试,并使用@Autowired对该构造函数进行注释而不是对字段进行注释。 因此,简而言之,请使用构造函数注入而不是字段注入。