alwaysAStudent
alwaysAStudent

Reputation: 2274

Perl Unit Test Mocking

I am attempting write a unit test in Perl by mocking. Its my first attempt at mocking.

Method is defined in MyConnect.pm

sub connect_attempt {
my ($a, $b, $c) = @_; 
// some calculation with $c
$status = connect( $a, $b );
return status;
}

connect is subroutine defined in Socket module. I need to test two scenario

1) Connection successful - To test this I am planning to return a new mock object or string
2) Connection unsuccessful - Status will remain undefined

MyConnect.t

use MyConnect;
use Socket;
my $status;
my $mock = Test::MockObject->new();
my $connect_module = Test::MockModule->new('MyConnect');
$connect_module->mock( 'connect_attempt' => sub { return "true"});
my $socket_module = Test::MockModule->new('Socket');
$socket_module->mock( 'connect' => sub { return "true"});
$status = $connect_module->connect_attempt("122", "53", 0);
ok(defined $status, 'Its fine');

I get the below error:

Cant locate object method "connect_attempt" via package "Test::MockModule" at t/MyConnect.t line 21.
#Looks like your test exited with 9 before it could output anything.
Dubious, test returned 9 (wstat 2304, 0x900)`
Line 21 is the call `$status = connect_attempt("122", "53", 0);

As per my understanding, I have created MockModule for my Module(MyConnect) and Socket module since I will invoking connect subroutine from it. I have set the response from both subroutines to be true. I should be expecting $status to true as well.

Can someone please explain where I am going wrong. This is my first unit test with mocking. I may have misunderstood certain concept.

Thanks

Upvotes: 1

Views: 1981

Answers (1)

stevieb
stevieb

Reputation: 9296

I believe this is because you're using the object oriented usage of the module, but your original module isn't OO.

Change:

$status = $connect_module->connect_attempt("122", "53", 0);

...to:

$status = MyConnect::connect_attempt("122", "53", 0);

...or, change your MyConnect to be OO:

package MyConnect;

sub new {
    return bless {}, shift;
}

sub connect_attempt {
    my ($a, $b, $c) = @_;
    $status = connect( $a, $b );
    return status;
}
1;

...then change this:

$status = $connect_module->connect_attempt("122", "53", 0);

...to this:

my $mocked_myconnect = MyConnect->new;
$status = $mocked_myconnect->connect_attempt("122", "53", 0);

Upvotes: 1

Related Questions