Fellow ``I love Perl so much, I can taste what Larry is having for dinner when I eat'' monks:

I pretty much always write my code in OO style, so that I never have to fear pissing on an imported name. In fact, most of my 'objects' are an empty shell. Essentially, I've standardized my coding style so that all opts/params *must* be name-based within an href, and that each sub call *must* be prefixed with either $obj-> or Class->

My tests are normally written about two lines ahead of the actual code it will be testing. Normally, each t/N-sub.t contains numerous code blocks, each block contains a single test I want to perform against the sub, eg:

# t/22-date.t { # date() my $obj = ISP::Object->new(); my $ret = $obj->date(); isa_ok( $ret, 'DateTime', "calling date() with no params, return" +); } { # date() get param my $obj = ISP::Object->new(); my $ret = $obj->date({ get => 'month' }); ok( $ret =~ m{ \A \d{4}-\d{2} \z }xms, "called with get=>month wor +ks out ok" ); }

I'm sick of duplicating code, especially within tests. I have mitigated some of this by wrapping the instantiation code within an internal sub, but now I have to carry globals:

{ # add_trace() trivial _reset(); my $ret = $error->add_trace(); is ( $ret, 0, "add_trace() returns success (0) when successful" ); } { # add_trace() type _reset(); $error->add_trace(); my $type = reftype $error->stack(); is ( $type, 'ARRAY', "Error's stack trace is an array ref upon suc +cess" ); }

I've heard that there are some modules that provide an oo and procedural interface. Although I haven't looked at any said code, what I'd like to do is instantiate an object via any method the class offers, perform only the task that method is supposed to, and return the result without having to build everything.

I'm wondering if each method should just call something else other than new() if $self isn't a reference. A basic 'what I'm thinking' is this (compacted for brevity ;) :

# in the package sub new { my $class = shift; # suck in a config, bless and populate $self return $self; } sub one_call_only { return bless {}, shift; } sub attach { my $thing = shift; my $self = ( ref $thing ) ? $thing : $thing->one_call_only(); # do attach() stuff with $self, and...: return $self->{ sub_details }; }

So, instead of manually instantiating a new object in my tests within each block (or if I want to use one method within an object) without having to perform the elaborate and time-consuming work that new() performs, I'm looking for other options.

fwiw, just for the `what I've tried' aspect, this is a basic routine that seems very simple. However, if I call it against the full-blown object, there are significant sanity checks performed, along with other self-building. That extra overhead is very cumbersome when trying to write tests.

sub attach { my $self = shift; my $params = shift; if ( $params->{ filename } && -e $params->{ filename } ) { my $filename = $params->{ filename }; my $mime_type = mimetype( $filename ); push @{ $self->{ attachments } }, { Path => $filename, Type => $mime_type }; } return $self->{ attachments }; # aoh }

Feedback and pointers to other code very much welcome

Steve


In reply to Saving keystrokes writing test suites by stevieb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.