OpenQuality.ru

Качество программного обеспечения

Качество программного обеспечения: в главных ролях

Лента  Радар  Блог  Опыт  
Разум  Видео  Заметки  Эпизоды


Perl: заглушки на классы, методы и объекты

Добрый день.

Модуль Test::MockObject может оказаться полезным при эмуляции объектов и методов избранного класса. Для его установки и работы потребуются Module::Build, UNIVERSAL::isa, UNIVERSAL::can.

Рассмотрим небольшой пример. Пакет Bug.pm содержит методы для работы с багами, найденными в программном коде.

package Bug;
 
sub new {
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self  = {};
    $self->{SEVERITY}  = undef;
    $self->{COMMENTS}  = [];
    bless ($self, $class);
    return $self;
}
 
sub severity {
    my $self = shift;
    if (@_) { $self->{SEVERITY} = shift }
    return $self->{SEVERITY};
}
 
sub comments {
    my $self = shift;
    if (@_) {
            $new_comment = shift;
            push(@{ $self->{COMMENTS} }, $new_comment);
    }
    return $self->{COMMENTS};
}
 
1;

Файл example1.pl служит примером обращения к методам класса:

#!/usr/bin/perl -w
use Bug;
use strict;
 
my ($severity, $comment, $comments);
my $bug = Bug->new();
 
$bug->severity ("Major");
 
$bug->comments("First Comment");
 
$bug->comments("Second Comment");
 
$comments = $bug->comments();
 
$severity = $bug->severity();
 
print "$severity\n";
 
foreach $comment (@ {$comments}) {
   print "$comment\n";
}
stylus:/tmp/Work # perl example1.pl
Major
First Comment
Second Comment

Установим заглушки на класс и его методы:

#!/usr/bin/perl -w
use Test::MockObject;
use strict;
 
my ($bug, $severity, $comment, $comments);
 
my $mock = Test::MockObject->new();
 
Test::MockObject->fake_module('Bug',
                               new  => sub { $mock });
 
$mock->mock('comments',
              sub {
                     return ["Mocked First Comment",
                             "Mocked Second Comment",
                             "Mocked Third Comment"];
              });
 
$mock->set_always("severity", "Mocked Severity");
 
 
$bug = Bug->new();
 
$comments = $bug->comments();
 
$severity = $bug->severity();
 
print "$severity\n";
 
foreach $comment (@ {$comments}) {
   print "$comment\n";
}

Исходный класс Bug не загружен. Вместо него создан псевдокласс Bug с собственными методами.

stylus:/tmp/Work # perl example2.pl
Mocked Severity
Mocked First Comment
Mocked Second Comment
Mocked Third Comment

Подробные сведения о Test::MockObject можно почерпнуть в документации к модулю (perldoc Test::MockObject).

Отметим некоторую путаницу в терминах, которая возникает при использовании Test::MockObject. Согласно классификации Фаулера, представленное решение в большей степени подпадает под определение “заглушки” (stubs), нежели “имитаторы” (mocks). Терминология модульного тестирования не устоялась и по сей день, поэтому подобные расхождения легко объяснимы и не являются препятствием при создании тестов.

Управление модульными тестами в Perl легко организовать на основе пакетов, входящих в стандартную поставку (Test::Simple, Test::More). Дополнительную функциональность можно получить с помощью модулей, доступных на CPAN. Вот некоторые из них: Test::Unit, Test::Class, Test::SimpleUnit. Выбор в соответствии с контекстом будет наиболее эффективным.

См. также: Заглушки на подпрограммы в Perl.

Отправить в Twitter, Facebook, ВКонтакте | Опубликовано 03.03.2009 в рубрике "Модульные тесты"

Комментарии (6)

  1. Автор комментария : Ivanych | March 3, 2009

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

    [Ответить]


  2. Автор комментария : Капитан Аляска | March 3, 2009

    Ivanych, ответил в комментарии к предыдущей статье.

    [Ответить]


  3. Автор комментария : Dmitry | March 3, 2009

    А что это вы там пишете такое, не багтрекинговую ли систему на Perl?

    [Ответить]


  4. Автор комментария : Капитан Аляска | March 4, 2009

    Dmitry, нет, это просто пример – раз объектом нашего внимания являются баги :) Системы отслеживания багов, написанные на Perl, есть уже довольно давно. Bugzilla, в частности.

    [Ответить]


  5. Автор комментария : Eldhenn | April 7, 2010

    Замечательные статьи. Только примеры в них используются слишком сложные. Нужно было писать на примере программы “Hello, world!” для большей понятности. Тогда сразу будет ясно, как метод, прекрасно работающий в программе из одной строки, работает в проекте из десятков модулей и тысяч строк.

    [Ответить]


  6. Автор комментария : Капитан | April 8, 2010

    Eldhenn, спасибо за теплые слова!

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

    [Ответить]



Добавить комментарий

Пожалуйста, исправьте результат: дважды два равно



КРАТКОЕ СОДЕРЖАНИЕ

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


ПУТЕВОДИТЕЛЬ

Проект был основан в 2008 году. За это время часть статей устарела, а некоторые из них вызывают улыбку, но пусть они останутся в том виде, в котором были написаны. Cписок всех статей с краткой аннотацией и разбивкой по рубрикам: открыть.

ПОДПИСКА

Доступ к самым интересным материалам по электропочте и RSS. Подробности.

ИЩЕЙКА