Опитвам се да се подигравам с функция в Net :: Twitter:
use strict;
use warnings;
use Test::MockModule;
my $mock = Test::MockModule->new("Net::Twitter");
$mock->redefine("update", sub {
# ...
});
но когато стартирам това, получавам:
Net :: Twitter :: update не съществува! на wtf.pl ред 8.
Защо е така и как всъщност мога да се подигравам Net::Twitter::update
функционира?
Отговори:
5 за отговор № 1Съобщението за грешка означава, че не може да бъде намерено Net::Twitter::update
за презаписване. Това е доста ясно. Въпросът е, защо?.
Ако погледнете a Net :: Twitter обект с Данни :: Printerще видите, че наистина няма update
метод. Всъщност това дори не е обект от типа Net::Twitter
.
use Net::Twitter;
use Data::Printer;
my $t = Net::Twitter->new;
p $t;
На моята машина с най-новата инсталирана Net :: Twitter, тя е Net::Twitter_v4_01042_with__Legacy
, което вероятно е динамично създаден пакет.
Net::Twitter_v4_01042_with__Legacy {
Parents Net::Twitter::Core
public methods (22) : apihost, apirealm, apiurl, arrayref_on_error, BUILD, DESTROY, has_error, http_code, http_message, is_list_member, is_list_subscriber, is_subscribed_list, meta, new, searchapiurl, trends, tvhost, tvrealm, tvurl, twittervision, update_twittervision, upload_url
private methods (5) : _clear_error, _error_return_val, _http_response, _parse_result, _twitter_error
internals: {
apirealm "Twitter API",
apiurl "https://api.twitter.com/1",
arrayref_on_error 0,
clientname "Perl Net::Twitter",
clienturl "http://search.cpan.org/dist/Net-Twitter/",
clientver 4.01042,
decode_html_entities 0,
_error_return_val undef,
_json_handler Cpanel::JSON::XS,
<<MOP>> Class::MOP::Class::Immutable::Moose::Meta::Class,
netrc_machine "api.twitter.com",
searchapiurl "https://search.twitter.com",
source "twitterpm",
ssl 1,
tvhost "twittervision.com:80",
tvrealm "Web Password",
tvurl "http://twittervision.com",
twittervision 0,
upload_url "https://upload.twitter.com/1",
useragent "Net::Twitter/4.01042 (Perl)",
useragent_args {},
useragent_class "LWP::UserAgent"
}
}
Ако опитате търся си sub update
в цялата дистрибуция на Net :: Twitter, Вие няма да намерите нищо. Не е част от роля, просто не съществува.
Но това не означава, че не е там. Изкопах малко по-дълбоко и намерих един update
в мрежата :: Twitter :: Role :: API :: REST, Определя се с помощта на twitter_api_method
функция от Net :: Twitter :: API, Той прави куп неща и след това използва мета слоя на Moose, за да инсталира метода в някой клас - вероятно Net::Twitter_v4_01042_with__Legacy
на моята машина '- и дори носи свой собствен клас мета метод Net :: Twitter :: :: Мета Метод.
Така че е доста очевидно защо Тест :: MockModule нямаше да намери Net::Twitter::update
, Просто никога
Но как да се подиграваме за тестване?
Вярвам, че най-простият подход, макар със сигурност не е много хубав, е да се презапише update
в пакета, в който съществува. За това трябва да създадете обект и да проверите.
use strict;
use warnings;
use Test::MockModule;
use Net::Twitter;
my $mock = Test::MockModule->new( ref( Net::Twitter->new ) );
$mock->redefine(
"update",
sub {
... # will die with "unimplemented"
}
);
my $nt = Net::Twitter->new->update;
Този код е малко разточителен, защото трябва да създаде обект само за да провери в кой пакет е стигнал, но работи.
Не се изпълнява в /home/simbabque/code/scratch/scratch.pl ред 236.