2013-02-26 59 views
7

我想測試一下連接到AdWords API的代碼,但沒有真正打電話給Google(這需要花費;))。任何想法如何我可以插入TrafficEstimatorServiceInterface的新實現?模擬adwords api

AdWords客戶端API正在使用Guice進行依賴注入,但我不知道如何才能獲得注入器的控制權來修改它?

如果有幫助,我這是怎麼弄的,現在執行:

AdWordsServices adWordsServices = new AdWordsServices(); 
    AdWordsSession session = AdwordsUtils.getSession(); 

    TrafficEstimatorServiceInterface trafficEstimatorService = 
      adWordsServices.get(session, TrafficEstimatorServiceInterface.class); 
+0

而不是改變吉斯被注射的方式,可你只是通過傳遞自己實現TrafficEstimatorServiceInterface和記錄測試你的方法是什麼操作運行它? – 2015-01-15 00:50:25

回答

0

您應該使用test account用於此目的。此外,從2013年3月1日起,將不再有charge for using the AdWords API,但在開發工具時仍應繼續使用測試帳戶。

+2

雖然這是有用的信息,但具體問題是如何控制Guice依賴注入,以便Google不*聯繫。我推測單元測試,而不是集成測試。 – 2015-01-15 00:48:54

0

您需要在測試代碼中注入Google API對象的測試實現(模擬/存根)。 Google在內部使用的Guice注入與此無關。

您應該使您的代碼依賴於TrafficEstimatorServiceInterface並在運行時注入它,而不是讓您的代碼從AdWordsServices工廠獲取TrafficEstimatorServiceInterface。然後,在你的單元測試中,你可以注入一個模擬或存根。

參見例如Martin Fowler的「Inversion of Control Containers and the Dependency Injection pattern」。

這對你來說在實踐中看起來取決於你用來運行你的應用程序的IoC容器。如果你使用Spring啓動,這可能是這個樣子:

// in src/main/java/MyService.java 
// Your service code, i.e. the System Under Test in this discussion 
@Service 
class MyService { 
    private final TrafficEstimatorServiceInterface googleService; 

    @Autowired 
    public MyService (TrafficEstimatorServiceInterface googleService) { 
    this.googleService = googleService; 
    } 

    // The business logic code: 
    public int calculateStuff() { 
    googleService.doSomething(); 
    } 
} 

// in src/main/java/config/GoogleAdsProviders.java 
// Your configuration code which provides the real Google API to your app 
@Configuration 
class GoogleAdsProviders { 
    @Bean 
    public TrafficEstimatorServiceInterface getTrafficEstimatorServiceInterface() { 
    AdWordsServices adWordsServices = new AdWordsServices(); 
    AdWordsSession session = AdwordsUtils.getSession(); 

    return adWordsServices.get(session, TrafficEstimatorServiceInterface.class); 
    } 
} 

// in src/test/java/MyServiceTest.java 
// A test of MyService which uses a mock TrafficEstimatorServiceInterface 
// This avoids calling the Google APIs at test time 
@RunWith(SpringRunner.class) 
@SpringBootTest 
class MyServiceTest { 

    @Autowired 
    TrafficEstimatorServiceInterface mockGoogleService; 

    @Autowired 
    MyService myService; 

    @Test 
    public void testCalculateStuff() { 
     Mockito.when(mockGoogleService.doSomething()).thenReturn(42); 

     assertThat(myService.calculateStuff()).isEqualTo(42); 
    } 

    @TestConfiguration 
    public static class TestConfig { 
     @Bean() 
     public TrafficEstimatorServiceInterface getMockGoogleService() { 
      return Mockito.mock(TrafficEstimatorServiceInterface.class); 
     } 
    } 
}