Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to specify correct prototype for mock method #27

Open
sidey79 opened this issue Sep 20, 2018 · 6 comments
Open

Add option to specify correct prototype for mock method #27

sidey79 opened this issue Sep 20, 2018 · 6 comments

Comments

@sidey79
Copy link

sidey79 commented Sep 20, 2018

If i try to mock the following sub:

sub foo($$$)
{
  return undef;
}

using the mock method:

my $foo = $mock->mock('foo');

I get a prototype mismatch warning:

PERL WARNING: Prototype mismatch: sub main::foo ($$$) vs none at /usr/local/share/perl/5.18.2/Mock/Sub/Child.pm line 122.

I already tried to disable the warnings, but this has no effect.
use Mock::Sub no_warnings => 1;

I cant figure out, how to specify the foo sub correctly

@stevieb9
Copy link
Owner

stevieb9 commented Sep 20, 2018 via email

@sidey79
Copy link
Author

sidey79 commented Sep 20, 2018

thank for your quick reply.

@stevieb9
Copy link
Owner

stevieb9 commented Sep 20, 2018 via email

@stevieb9
Copy link
Owner

stevieb9 commented Sep 21, 2018

I've come up with a quick and dirty workaround for this issue. Essentially, you can just trap the prototype warnings and prevent them from being displayed. It's not optimal but it does work. Note though that even though the warnings are quelled, you still have to send in the proper number of parameters to the mocked sub:

use warnings;
use strict;
use feature 'say';

use Mock::Sub;

# display all warnings that aren't related to prototypes, and silence
# the warnings that are

$SIG{__WARN__} = sub {say $_[0] if $_[0] !~ /Prototype/};

my $m = Mock::Sub->new;

sub foo ($$$){
    say "hello!"; # doesn't get called
    return undef;
}

my $foo = $m->mock('foo');
$foo->return_value('test');

say foo(1, 2, 3);
say foo(1, 2, 3);
say foo(1, 2, 3);

say $foo->called_count;

Output, to ensure the mocked sub is actually the one being executed:

test
test
test
3

Let me know what you think about this workaround. If it seems sane (enough), I'll add this functionality to the Mock::Sub distribution directly so the user doesn't have to write the signal handler into their scripts.

If that's the way I go, I'll likely make the user send in a parameter to specify they want this functionality. Essentially, if a user runs into this issue, they can have the option to use the feature directly. I'd rather play it safe by default so the user isn't confused, and then they can silence the warnings. Best that someone knows about a potential problem and be able to selectively work around it, then hide the warnings by default which would probably confuse people.

Besides, I don't like implementing sig handlers blindly particularly when 99% of users won't need it.

Also, note that the no_warn flag isn't a signal handler. It's only purpose is to silence a warning that I throw from within the code itself (a warning when mocking a non-existent sub). This is why it didn't have the effect of silencing the prototype warnings.

@sidey79
Copy link
Author

sidey79 commented Sep 22, 2018

I'll Check this later, but i think adding a method which disables the warning ist okay.

@sidey79
Copy link
Author

sidey79 commented Sep 22, 2018

I've tested it and it works.

But i specified say full qualified, so no need to provide a use feature say.

	# Disable warnings for prototype mismatch
	$SIG{__WARN__} = sub {CORE::say $_[0] if $_[0] !~ /Prototype/};

I think, after running a test it is may be good to restore the original behaviour

	# enable warnings for prototype mismatch
	$SIG{__WARN__} = sub {CORE::say $_[0]};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants