当前位置: 代码迷 >> java >> 将模拟的多个排列应用于依赖项,以便在Spring中进行更好的单元测试
  详细解决方案

将模拟的多个排列应用于依赖项,以便在Spring中进行更好的单元测试

热度:36   发布时间:2023-07-31 13:35:30.0

假设我有一个类(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(以及必要的必要的内部管理)。

这是一个使用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对该构造函数进行注释而不是对字段进行注释。 因此,简而言之,请使用构造函数注入而不是字段注入。

  相关解决方案