2013-02-26 2 views
7

Я хочу проверить свой код, который подключается к API AdWords, без фактического вызова в Google (что стоит денег;)). Любая идея, как я могу подключить новую реализацию TrafficEstimatorServiceInterface?mock adwords api

API-интерфейс клиента AdWords использует Guice для инъекций зависимостей, но я не уверен, как я могу удержать Инжектор, чтобы изменить его ?!

Если это помогает, это то, как я получаю реализацию этого сейчас:

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

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

Вместо того, чтобы изменить способ Guice впрыскивает, вы можете просто проверить свои методы, передавая в собственной реализации TrafficEstimatorServiceInterface и записи, какие операции выполняются на Это? –

ответ

0

Вы должны использовать test account для этой цели. Кроме того, с 1 марта 2013 года не будет charge for using the AdWords API, но при разработке вашего инструмента вы должны продолжать использовать тестовую учетную запись.

+2

Как бы это ни было полезно, вопрос конкретно задает вопрос о том, как управлять инъекцией зависимостей Guice, так что google не связан *. Я полагаю, что для модульного тестирования в отличие от тестирования интеграции. –

0

Вам необходимо ввести тестовую реализацию (mock/stub) объектов API Google в ваш тестовый код. Ввод Guice, который использует Google внутри, здесь не уместен.

Необходимо, чтобы ваш код зависел от TrafficEstimatorServiceInterface и вводил его во время выполнения, вместо того, чтобы получить код, полученный TrafficEstimatorServiceInterface с фабрики AdWordsServices. Затем в ваших модульных тестах вы можете ввести макет или заглушку.

См., Например, «Inversion of Control Containers and the Dependency Injection pattern» от Martin Fowler.

Как это будет выглядеть на практике, зависит от того, какой контейнер 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); 
     } 
    } 
} 
Смежные вопросы