Как я могу переопределить коммит на моем $ dbh для тестирования? - PullRequest
2 голосов
/ 17 ноября 2010

Я пытаюсь изменить свой тест, чтобы любая работа с базой данных откатывалась по завершении. Однако кажется, что где-то в коде, который я тестирую, явно вызывается $ dbh-> commit. Есть ли способ переопределить метод commit объекта DBI :: db для полного поворота коммитов?

Я пытался использовать Test :: MockObject :: Extends, но это, похоже, наносит вред $ dbh:

    $dbh = ConnectToDB();
    $dbh = Test::MockObject::Extends->new( $dbh );
    $dbh->mock( 'commit', sub { warn("Caught you committing.") } );

Позже, когда я пытаюсь использовать $ dbh для выполнения какой-то работы, я получаю:

Не удалось найти метод объекта "fetchrow_array" через пакет "T :: MO :::: st"

Похоже, $ sth, которые я в итоге создал с помощью смоделированного $ dbh, настроены неправильно. У кого-нибудь есть хороший способ полностью отключить коммиты для определенного $ dbh?

База данных, к которой я подключаюсь, - Oracle, для чего она стоит.

Обновление

Как оказалось, мы переопределяли & DBI :: db :: commit в методе, очень похожем на ответ Axeman, но на самом деле фиксация происходила из-за неконтролируемого коммита в хранимой процедуре, вызываемой во время выполнения мой тест.

Ответы [ 4 ]

2 голосов
/ 18 ноября 2010

Можно использовать атрибут Callbacks для перехвата и игнорирования вызова метода commit ().

2 голосов
/ 17 ноября 2010

Юнит-тесты вообще не должны говорить о реальной базе данных.Одним из распространенных подходов является замена драйвера базы данных на поддельный с помощью DBD :: Mock , DBD :: CSV или SQLite , что позволяет использовать изолированныйданные испытаний, настроенные для каждого набора тестов, которые можно стирать после каждого запуска и / или сохранять для анализа.

1 голос
/ 17 ноября 2010

Вы могли бы реализовать эту идею вопросов и ответов:

{
    my %old_commit;
    sub toggle_commit { 
        my $dbh   = shift;
        my $class = blessed( $dbh );
        if ( my $old_commit = $old_commit{ $class } ) {
            my $symb 
                = do { no strict 'refs'; 
                       \*{ "$class\::commit" };
                };

            *$symb = undef;
            unless ( $class->can( 'commit' )) { 
               *{ $symb } = $old_commit;
            }
            delete $old_commit{ $class };
        }
        else {
            $old_commit{ $class } = $class->can( 'commit' );
            {   no strict 'refs'; 
                *{ "$class\::commit" } = sub { say "Committed!" };
            }
        }

    }
} 

Да, это достаточная степень черной магии Perl.

Вам придется проверить это на здравомыслие.Так как это следует использовать только при тестировании , вы должны иметь возможность разбить код на части, чтобы не было возможности возиться подобным образом в любом работающем коде.

0 голосов
/ 17 ноября 2010

Полагаю, вы хотите отключить AutoCommit при подключении.

...