Как проверить состояние ссылки в Perl? - PullRequest
4 голосов
/ 15 июня 2011

G'Day,

Я пытаюсь выполнить модульное тестирование функции, которая использует оператор вроде:

unless($this->_doc_type eq ref($this->_doc_instance)) {
    # Do something
} 

Независимо от того, как я высмеиваю свои объекты, вы не можете обмануть ref (). Как мне пройти тестирование?

  • есть приватная ref() функция, которая вызывает CORE::ref()?
  • попробовать переопределить CORE::ref в моих модульных тестах?
  • ???

1 Ответ

3 голосов
/ 15 июня 2011

В старые добрые времена у нас был код вида

switch (item->type) {
  case FOO:
    do_foo(item);
    break;

  case BAR:
    do_bar(item);
    break;

  default:
    handle_unknown_type(item->type, __FILE__, __LINE__);
    break;
}

Эта схема явной проверки типов элементов и последующего перехода к различным функциям повторялась много раз по всему источнику системы.

Когда пришло время добавить новый тип BAZ в микс, это означало вернуться назад и прикоснуться к каждой цепочке switch, if / else или к любому другому условию, включающему item->type.

Это была большая боль.

Объектно-ориентированные языки впитывают этот шаблон, поэтому программисту не нужно переопределять его повсеместно и не нужно тратить умственные ресурсы на этот низкоуровневый процесс. Когда якобы объектно-ориентированный код жаждет плохих старых времен, как в

unless ($this->_doc_type eq ref($this->_doc_instance)) { ... }

это сильный запах кода.

Мое первое предложение - переделать производственный код. Что происходит внутри условного? Какова цель этого кода?

Полагаю, вы использовали макеты для _doc_instance. Чтобы получить поддержку тестирования перед рефакторингом кода, я хотел бы посмотреть, как изменить значение, возвращаемое с _doc_type, которое, как я полагаю, не является простым средством получения. Не зная ничего о контексте, один из подходов заключается в создании подкласса тестирования.

Скажите, что вы тестируете класс My::Container. Если вам удастся избежать фальшивого документа для этого конкретного теста (который имеет только внешний вид реального документа), напишите код в соответствии с

package Test::My::Container_Canned_Type;

use base 'My::Container';

sub _doc_type { "Test::Fake::Document" }

1;

и затем в своем тесте используйте его как в

my $doc = bless {} => "Test::Fake::Document";
my $c   = Test::My::Container_Canned_Type->new($doc, ...);

Если я неправильно угадал структуру вашего кода, предоставьте больше контекста, чтобы мы могли дать вам больше полезных советов!

Нахождение себя в этом трудном месте - хороший урок, почему полезно писать тесты first . Умышленно вы исключаете случаи, когда вы чесаете голову и задаетесь вопросом, как проверить странную реализацию.

Резюме

  • Нет, не пытайтесь изменить работу ref.
  • По возможности исключите использование ref в вашем производственном коде.
...