Как проверить частную функцию в Dart?

Скажем, я определил частную функцию в файле дротика hello.dart:

_hello() {
  return "world";
}

Я хочу протестировать его в другом файле mytest.dart:

library mytest;

import 'dart:unittest/unittest.dart';

main() {
  test('test private functions', () {
    expect(_hello(), equals("world"));
  }
}

Но, к сожалению, тестовый код не может быть скомпилирован. Но мне нужно проверить эту частную функцию _hello. Есть ли какое-либо решение?

Ответ 1

Несколько человек считают, что нам не следует проверять конфиденциальность напрямую: он должен быть протестирован через открытый интерфейс.

Преимущество этого руководства состоит в том, что ваш тест не будет зависеть от вашей реализации. Говорите по-другому: если вы хотите изменить свой личный, не изменяя то, что вы открываете миру, вам не придется прикасаться к вашим тестам.

В соответствии с этой школой, хотя, если ваш частный достаточно важен, чтобы оправдать unit test, тогда имеет смысл извлечь его в новый класс.

Объединив все это, вы можете сделать следующее:

  • Создайте класс-помощник с помощью этого метода hello как общедоступный. Затем вы можете легко unit test it
  • Пусть ваш текущий класс использует экземпляр этого вспомогательного класса
  • Протестируйте общедоступные методы вашего текущего класса, которые полагаются на _hello: если у этого частного есть ошибка, он должен быть улавливан этими тестами более высокого уровня

Ответ 2

Хотя я согласен с тем, что закрытые методы/классы не должны быть частью ваших тестов, @visibleForTesting предоставляет атрибут @visibleForTesting, и анализатор выдаст вам предупреждение, если вы попытаетесь использовать член вне его исходной библиотеки или теста, Вы можете использовать это так:

import 'package:meta/meta.dart';
...
@visibleForTesting
hello() {
    return "world";
}

Теперь ваши тесты смогут использовать его без ошибок или предупреждений, но если кто-то попытается использовать его, он получит предупреждение.

Опять же, в отношении мудрости выполнения этого это другой вопрос - обычно, если это что-то стоит протестировать, это что-то, что стоит того, чтобы быть публичным (или это будет проверено через ваши публичные интерфейсы и то, что действительно имеет значение в любом случае). В то же время, вы можете просто захотеть проводить строгие тесты или принципы, основанные на тестировании, даже для ваших частных методов/классов, поэтому Dart позволяет вам это.

Изменить, чтобы добавить: Если вы разрабатываете библиотеку и ваш файл с @visibleForTesting будет экспортирован, вы по сути добавляете публичный API. Кто-то может потреблять это с выключенным анализатором (или просто игнорировать предупреждение), и если вы удалите его позже, вы можете сломать его.