2013-02-26 62 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); 
     } 
    } 
}