Как я тестирую инжекции Guice?

С небольшим упрощением:

Внутри блока { ... }, int k = 0; создает переменную, и эта переменная существует до того момента, когда вы достигнете конца блока, и там переменная разрушается. Таким образом, в любой момент во время выполнения программы существует не более одного n, j или k.

Немного ближе к реальности:

Компилятор просматривает весь метод, находит список переменных, которые могут существовать параллельно (i, n, j, k и foundIt), и выделяет достаточно места в стеке для этих переменных (5 мест в вашем примере). Эти места в стеке существуют с момента, когда вы вводите свой метод, до тех пор, пока вы не вернетесь из него, но они не используются постоянно, например, место k содержит только полезные значения с момента выполнения int k = 0; до конца итерации текущего цикла.

30
задан Pang 15 May 2018 в 04:21
поделиться

4 ответа

Для любого сложного проекта Guice вы должны добавить тесты, чтобы убедиться, что модули можно использовать для создания ваших классов. В вашем примере, если B был типом, который Guice не мог понять, как создать, тогда Guice не сможет создать A. Если A не требовался для запуска сервера, но был необходим, когда ваш сервер обрабатывал запрос, который вызовет проблемы.

В своих проектах я пишу тесты для нетривиальных модулей. Для каждого модуля я использую requireBinding () , чтобы объявить, какие привязки модуль требует, но не определяет. В своих тестах я создаю инжектор Guice, используя тестируемый модуль и другой модуль, который предоставляет необходимые привязки.Вот пример использования JUnit4 и JMock:

/** Module that provides LoginService */
public class LoginServiceModule extends AbstractModule {
  @Override 
  protected void configure() {
    requireBinding(UserDao.class);
  }

  @Provides
  LoginService provideLoginService(UserDao dao) {
    ...
  }
}

@RunWith(JMock.class)
public class LoginServiceModuleTest {
  private final Mockery context = new Mockery();

  @Test
  public void testModule() {
    Injector injector = Guice.createInjector(
        new LoginServiceModule(), new ModuleDeps());

    // next line will throw an exception if dependencies missing
    injector.getProvider(LoginService.class);
  }

  private class ModuleDeps extends AbstractModule {
    private final UserDao fakeUserDao;

    public ModuleDeps() {
      fakeUserDao = context.mock(UserDao.class);
    }

    @Override 
    protected void configure() {}

    @Provides
    Server provideUserDao() {
      return fakeUserDao;
    }
  }
}

Обратите внимание, что тест запрашивает только поставщика. Этого достаточно, чтобы определить, что Guice может разрешить привязки. Если LoginService был создан методом поставщика, этот тест не будет проверять код в методе поставщика.

Этот тест также не проверяет, правильно ли вы связали UserDao или что область UserDao была правильно определена. Некоторые утверждают, что такие вещи редко стоит проверять; если есть проблема, это случается один раз. Вы должны «тестировать, пока страх не превратится в скуку»

. Я считаю, что модульные тесты полезны, потому что я часто добавляю новые точки внедрения, и легко забыть добавить привязку.

Вызовы requireBinding () могут помочь Guice обнаружить недостающие привязки до того, как он вернет ваш инжектор! В приведенном выше примере тест все равно работал бы, если бы не было вызовов requireBinding () , но мне нравится их наличие, потому что они служат в качестве документации.

Для более сложных модулей (например, моего корневого модуля) я мог бы использовать Modules.override () , чтобы переопределить привязки, которые мне не нужны во время тестирования (например, если я хочу проверить, что мой корневой объект, который будет создан, я, вероятно, не хочу, чтобы он создавал объект, который будет подключаться к базе данных). Для простых проектов вы можете протестировать только модуль верхнего уровня.

Обратите внимание, что Guice не будет вводить нули , если поле не помечено @Nullable , поэтому вам очень редко нужно проверять, что введенные объекты не равны нулю в ваших тестах.Фактически, когда я аннотирую конструкторы с помощью @Inject , я не утруждаюсь проверять, являются ли параметры null (на самом деле, мои тесты часто вводят null в конструктор, чтобы тесты были простыми).

45
ответ дан 27 November 2019 в 23:58
поделиться

Еще один способ проверить вашу конфигурацию - это иметь набор тестов, который тестирует ваше приложение из конца в конец. Хотя сквозные тесты формально тестируют варианты использования, они косвенно проверяют, правильно ли настроено ваше приложение (что все зависимости подключены и т. Д. И т. Д.). Модульные тесты, с другой стороны, должны фокусироваться исключительно на домене, а не на контексте, в котором развернут ваш код.

Я также согласен с ответом NamshubWriter. Я не против тестов, которые проверяют конфигурацию, если они сгруппированы в отдельный набор тестов для ваших модульных тестов.

4
ответ дан murungu 27 November 2019 в 23:58
поделиться

Я не думаю, что вам следует проверять наличие закрытых пользователей. Лучше протестировать публичный интерфейс вашего класса. Если член "b" не будет введен, вы, вероятно, получите NullPointerException, выполняющий ваши тесты, что должно быть большим количеством предупреждения.

-1
ответ дан Alexander Malfait 27 November 2019 в 23:58
поделиться

IMHO, вам не следует это тестировать. У ребят из Google Guice есть модульные тесты, подтверждающие, что инъекции работают должным образом - в конце концов, именно для этого и предназначен Guice. Вы должны писать тесты только для своего собственного кода (A и B).

2
ответ дан 27 November 2019 в 23:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: