How to check ref condition in perl?

G'day,

I am trying to use a unit test function that uses an operator like:

unless($this->_doc_type eq ref($this->_doc_instance)) { # Do something } 

No matter how I mock my objects, you cannot fool ref (). How can I check this?

  • has a personal function ref() that calls CORE::ref() ?
  • try and override CORE::ref in my unit tests?
  • ???
+4
source share
1 answer

In the good old days, we had a form code

 switch (item->type) { case FOO: do_foo(item); break; case BAR: do_bar(item); break; default: handle_unknown_type(item->type, __FILE__, __LINE__); break; } 

This scheme of explicit control of element types and subsequent branching into different functions was repeated many times throughout the source of the system.

When it came time to add a new BAZ type to the BAZ , it meant returning and touching each switch chain, if / else or any other condition associated with item->type .

It was a big pain.

Object-oriented languages ​​absorb this pattern, so the programmer does not need to overestimate it everywhere and does not need to spend mental resources on this low-level plumbing. When supposedly object-oriented code craves old days, as in

 unless ($this->_doc_type eq ref($this->_doc_instance)) { ... } 

this is a strong smell of code.

My first suggestion is to reverse engineer the production code. What happens inside the conditional? What is the purpose of this code?

I assume you used mocks for _doc_instance . To get test support before code refactoring, I would look at how to change the value returned from _doc_type , which I also assume is not a simple getter. Without knowing anything about the context, one approach is to create a subclass of testing.

Say that the class you are testing is My::Container . If you can get away with a fake document for this particular test (which only has a surface look of a real document), write the code in lines

 package Test::My::Container_Canned_Type; use base 'My::Container'; sub _doc_type { "Test::Fake::Document" } 1; 

and then in your test, use it as in

 my $doc = bless {} => "Test::Fake::Document"; my $c = Test::My::Container_Canned_Type->new($doc, ...); 

If I misunderstood the structure of your code, provide more context so that we can give you more useful suggestions!

Finding yourself in this difficult place is a good lesson why the first research is useful. By design, you eliminate cases where you scratch your head and wonder how to test a strange implementation.

Summary

  • No, do not try to change the way ref works.
  • As far as possible, eliminate the use of ref in your production code.
+3
source

All Articles