I'm working with some co-workers to develop some best practices for unit test writing and we've run into at least one conflict over what that best practice should be. While there are a number of unresolved questions, the most contentious question was of the degree of isolation that is appropriate in tests. I am generally of the school of thought that isolation is always disable, so I make a lot of use of Test::MockModule and Test::MockObject.

Here's a simple example of some code I might write and the test I would write for it:

use strict; use warnings; use Test::More tests => 2; use Test::MockModule; my $mock_simple = Test::MockModule->new( 'Simple', no_auto => 1 ); $mock_simple->mock( foo => 1 ); $mock_simple->mock( bar => 'bar' ); $mock_simple->mock( baz => 'baz' ); my $simple = bless {}, 'Simple'; is( $simple->foobar, 'bar', 'got bar when foo is true' ); $mock_simple->mock( foo => 0 ); is( $simple->foobar, 'baz', 'got baz when foo is false' ); #################################################################### package Simple; sub foobar{ my $self = shift; if ( $self->foo() ){ return $self->bar(); } else{ return $self->baz(); } }

I find this useful because I don't have to care about what bar and baz actually do, especially if there is a lot of indirection involved in their implementation; i.e. I don't want to have to dig through three or four (or seven) layers of methods to figure out what to expect for the test.

However, there is a contingent at the office that thinks that setting up the object as implemented is a better option when reasonable. For example, if this was a CGI script and the foo, bar and baz methods were looking at CGI params to determine their return values, I would actually set those CGI params rather than mocking up the methods. The argument here is that this method provides at least a modicum of integration testing between the methods and is likely to uncover errors introduced by interface changes, intentional or otherwise.

What do y'all think? If isolation is generally desirable, are there other kinds of tests that we can use to try to catch other kinds of errors? We do a limited amount of testing with WWW::Mechnize. We actually do less than we used to since we've started taking unit test coverage more seriously and we have no standard as to what we test with mech tests.

perl -e 'split//,q{john hurl, pest caretaker}and(map{print @_[$_]}(joi +n(q{},map{sprintf(qq{%010u},$_)}(2**2*307*4993,5*101*641*5261,7*59*79 +*36997,13*17*71*45131,3**2*67*89*167*181))=~/\d{2}/g));'

In reply to Testing: To Mock or Not to Mock? by agianni

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.