How can I make fun of sub in another module?

I'm having problems mocking a subroutine in a different module than where I run the tests.

I have my tests in the ParserTests.pl file. I am trying to check a subroutine (parsing) in the LogParser.pm module

sub parse { my ($self) = @_; my $rr = $self->getRR; while(1) { my $result = $self->parseCommitSet(); if ($result eq 2) { last; } my $printStatus = $self->printOut($result); if (!$printStatus) { say "Problem occurred with writing to output"; return 0; } $self->setRR(ReportRecord->new()); } return 1; } 

I am trying to make fun of printOut so that it always returns true. I am trying to do the following:

 #! /usr/bin/perl use v5.10.0; use strict; use warnings; use Test::More 'no_plan'; use Test::MockObject; use LogParser; {other testsโ€ฆ} my $mock = Test::MockObject->new(); $mock->set_true('LogParser::printOut'); my $test100FH = getTestFH($test100SetsNoPrev); $logParser = LogParser->new($test100FH); is($logParser->parse, 1, "im ok?"); close $test100FH; 

But this test fails. Can you tell me why and point me to the right path to make it work correctly when I test parse ()? I read a bunch of documentation, but something like this is still a bit unclear.

Error

 Can't use an undefined value as a symbol reference at /Users/achu/Documents/workspace/Perl_Script/LogParser.pm line 241, <$fh> line 8371. # Looks like your test exited with 25 just after 91. 

This line (line 241) is inside the printOut subroutine, but this means that it does not mock this subroutine as I wanted it to. What am I doing wrong?

+6
source share
4 answers

Test::MockModule is probably better suited for this;

 my $module = Test::MockModule->new('LogParser'); $module->mock( printOut => sub { return 1 } ); 

This will cause LogParser to use your modified version until $module goes out of scope.

+10
source

Test::MockObject not quite what you want. This is good for providing a minimally implemented stub. But to create an instance of the test class and selectively override its methods, you want Test::MockObject::Extends .

TMOE takes an instance, and then lets you change what some of its methods do. In your example, you can use it to write a test this way:

 use Test::MockObject::Extends; my $test100FH = getTestFH($test100SetsNoPrev); $logParser = Test::MockObject::Extends->new( LogParser->new($test100FH); ); $logParser->set_true('printOut'); is($logParser->parse, 1, "im ok?"); close $test100FH; 
+5
source

You did not specify an error message, but you defined an object named $ mock that contains the printout method. But you call printout () in $ logparser.

The point of MockObject is to create a very bare object using several methods so that you can test other pieces of code in an algorithm that relies on an external object. For example, you could mock a database descriptor so that calling $ dbh-> fetchStuff () always returns to a static string so that you can test the code that consumes the string.

Thus, without unnecessary context, I canโ€™t say about the possibilities of simply creating a stub for printOut () so that the browser knows about it.

However, I also do not understand the desire to have a test for the return value of the hatched method.

+1
source

Read the documentation for Test :: MockObject and try to understand how this works.

You do only the first half of what is actually required: you create a mock object. But this does not magically end in your LogParser.

What Test::MockObject gives you is an object that behaves exactly like the object you want to make fun of. Of course, someone or something else should use this object. And that should be the code you are trying to verify.

-1
source

Source: https://habr.com/ru/post/946275/


All Articles