2017-06-15 85 views
0

我發現有關與的Mockito嘲諷的任何實例的工作原理類似於此接口(這些只是codesnipets):模擬更深層次的類/使用的Mockito

考慮:

public interface MyInterface { 
    public String doWhatever(); 
} 

public class MyClass { 
    @Autowired 
    MyInterface myInterface; 

    public String doSomething() { 
    return myInterface.doWhatever(); 
    } 
} 

嘲諷:

@Mock 
MyInterface myInterfaceMock; 

@InjectMocks 
MyClass myClass; 

@Test 
public void test() throws Exception { 
    when(myInterfaceMock.doWhatever()).thenReturn("foo"); 

    String result = myClass.doSomething(); 
    ... 
} 

然而,當引入第二類時,使用更深的級別:

public class MyOtherClass { 
    @Autowired 
    MyInterface myInterface; 

    public MyInterface getMyInterface() { 
     return myInterface; 
    } 
} 

更深層次的嘲諷類結構進行時,總是這樣的:

public class MyClass { 
    MyOtherClass myOtherClass = new MyOtherClass(); 

    public MyOtherClass getOtherClass() { 
     return myOtherClass; 
    } 
} 

@Test 
public void test() throws Exception { 
    given(myClass.getOtherClass().getMyInterface().doSomething()).willReturn("bar");   

    String result = myClass.getOtherClass().getMyInterface().doSomething(); 
} 

中查看information

然而,這並不能反映類結構我應該測試此深存根例子。給定結構如下:

public interface MyInterface { 
    public String doWhatever(); 
} 

public class MyOtherClass { 
    @Autowired 
    MyInterface myInterface; 

    public String doOtherThing() { 
    return myInterface.doWhatever(); 
    } 
} 

public class MyClass { 
    MyOtherClass myOtherClass = new MyOtherClass(); 

    public String doSomething() { 
    return myOtherClass().doOtherThing(); 
    } 
} 

現在,我想嘲弄它與此類似:

@Mock 
MyInterface myInterfaceMock; 

@InjectMocks 
MyClass myClass; 

@Test 
public void test() throws Exception { 
    when(myInterfaceMock.doWhatever()).thenReturn("foo"); 

    String result = myClass.doSomething(); 
    ... 
} 

當然,這是不行的,因爲模擬在MyOtherClass並注入不在MyClass中。但是,如果我將它注入MyOtherClass,我沒有MyClass的實例。

編輯:

導致我對這個問題的原因是,我應該做的microService級測試。可能是,我有錯誤的方法。我也可以通過模仿MyOtherClass來測試MyClass,並通過模仿MyInterface來測試MyOtherClass。

所以,這裏是有關給定微服務更詳細一點:

REST的API - > SomeCode - > SomeOtherCode - >其他-REST的API

出代碼覆蓋REST的API,SomeCode和SomeOtherCode。其他-REST-API是第三方,像Google,移動服務提供商等。

現在,我可以使用MockMVC測試REST-API並嘲諷SomeCode。我可以通過嘲笑Other-REST-API來單元測試SomeOtherCode。然而,我的目標是通過使用MockMVC測試整個鏈,做一些參數變化並嘲笑Other-TEST-API,以查看SomeCode和SomeOtherCode的行爲。

+0

我更新了我的解決方案,如果這是您正在尋找的內容,獲得一些反饋將會非常好... –

回答

0

所以發生什麼事是當@InjectMocks嘲笑正在尋找自動裝配的東西MyClass裏面注入,MyClass沒有任何,所以它沒有找到任何。

我懷疑這會工作,如果MyOtherClass@Autowired,但您可能還需要爲您的MyOtherClass@InjectMocks

+0

是的,您是對的。我將它改爲@Autowired。現在,它就像一個魅力。 –

0

根據您的更新: 您應該看看https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html - 在這裏您可以看到如何運行集成測試。您可以提供自己的彈簧XML

@ContextConfiguration("/test-config.xml") 
public class XmlApplicationContextTests { 
    // class body... 
} 

或Spring配置測試中的一類。

@ContextConfiguration(classes = TestConfig.class) 
public class ConfigClassApplicationContextTests { 
    // class body... 
} 

另外,你可以定義嘲笑和spys對XML與

<bean id="spyService" class="org.mockito.Mockito" factory-method="spy"> 
    <constructor-arg ref="service"/> 
</bean> 
<bean id="mockService" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="your.Service" /> 
</bean> 

或配置

@Configuration 
static class TestConfig { 
    @Bean 
    Service serviceMock() { 
     return mock(Service.class); 
    } 
    @Bean 
    Service serviceSpy() { 
     return spy(new Service()); 
    } 
} 

但實際上這是你怎麼做集成測試彈簧。

您還需要在這種情況下提供正確的UnitTestRunner SpringJUnitRunner。

@RunWith(SpringJUnitRunner.class) 
@ContextConfiguration(classes = TestConfig.class) 
public class MyClassComponentTest { 
    @Autowired 
    MyInterface myInterfaceMock; 

    @Autowired 
    MyClass myClass; 

    @Configuration 
    static class TestConfig { 
     @Bean 
     MyClass myClass() { 
      return new MyClass(); 
     } 
     @Bean 
     MyOtherClass myOtherClass() { 
      return new MyOtherClass(); 
     } 
     @Bean 
     MyInterface myInterfaceMock() { 
      return mock(MyInterface.class); 
     } 
    } 

    @Test 
    public void test() throws Exception { 
     when(myInterfaceMock.doWhatever()).thenReturn("foo"); 

     String result = myClass.doSomething(); 
     ... 
    } 
} 

老答案

的問題是:你應該用類似落得「?難道真的想單元測試」

因爲當你正在進行單元測試時,你根本不在乎MyOtherClass內發生了什麼 。你只需簡單地模擬MyOtherClass, ,然後編寫一個單元測試MyOtherClass,你可以模擬 MyInterface

其他問題,我在你的例子看到的是,你永遠不會 實例化MyOtherClass類的一個對象,一個是 從來沒有注入到你的MyClass -object,所以這可能其實並不 工作

+0

是的,thanx。這很接近。但是,看看我的示例,MyOtherClass類中的MyInterface實例未自動設置。我必須明確地用ReflectionTestUtils.setField(myOtherClass,「myInterface」,myIntefaceMock)來設置它。 –