2015-07-20 14 views
1

比方說,我有一個有一個方法orchestrate()調用了一些其他類(ClassA的的do1()方法,CLASSB的do2()法)的小方法的類(OrchestratingClass)。我想通過嘲笑各​​種排列的do1()do2()的響應來測試orchestrate()的行爲。我跑我的測試的東西,如:應用嘲笑到依賴性更好的單元測試的重複排列,在春季

@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的模擬版本,但是當我移動到test2()時,我被鎖定爲1特定模擬,並且無法「重新模擬」事物。我相信,如果我們試圖爲「每個測試」注入不同的「風味」bean,那麼在單個測試類中使用java配置文件將不起作用。有沒有人有任何建議,我可以做什麼,以確保我真的徹底地測試,而不是侵入性(例如:爲orchestratingClass中的特定類添加多餘的「setter」以側面注入bean注入痛苦)?從本質上講,我希望通過應用各種模擬來針對特定的感興趣的bean(以及必需的內務管理)在每個測試的基礎上「篡改」applicationContext。

+0

只是根本不使用Spring。你是一個標準的ocking框架(Mockito,EasyMock),可以創建一個模擬的ClassA和ClassB實例,完成你想要的任務。 –

+0

@JBNizet考慮到classA和classB在OrchestratingClass中實際是私有的,我很好奇我該如何在這種情況下實現side-step Spring。我想我的問題不是一個奇怪的角落案例,所以我認爲Spring會有一些鉤子來滿足這樣的要求。從你的答案看來,在春天沒有任何一流的方法來實現這個目標......這是正確的假設嗎? – BSJ

回答

2

下面是使用的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

請注意,即使沒有這種魔法,只需添加一個以ClassA和ClassB作爲OrchestratingClass參數的構造函數,然後使用@Autowired註釋構造函數而不是註釋這些字段即可輕鬆測試您的類。所以,總之,使用構造函數注入而不是字段注入。

+0

晶瑩剔透。非常感謝! – BSJ