locinus has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks.

I have been browsing for a while now for modules to manage and test an application, and came up with a possible model for mine. Yet, I'm quite new in Perl and don't master its logic and principles: hence, I'd like to ask any of you for an enlighted opinion about what I came up to so far, if you please.

Background

I've got an existing piles of scripts and modules, made by Perl rookies for urgent needs and with no hope that would grow any further. But it did, and now, with my poor knowledge of Perl, I am to try to organize the existing in a proper architecture the best I can.

The existing application

The main traits of the existing code are as follows, running on Perl 5.10:

The problem that really arises now is the unability of mocking the services that the processes use during our tests. Also, different tested processes might need different mocked services (as a basic example: most tests will want to avoid actually sending emails and to use a mocked emailing service instead; but one test could need the actual emailing service to check the real sending/receiving of emails).

A target framework to criticize

I've checked things like App::Cmd and CLI::Framework, but those seems to be designed merely to help managing different command-lines, and don't provide much functionnality for stubbing and such.
I've been checking App::Framework which seems to be very complete, and with some tweaks could maybe fit my needs, especially by providing a Dependency Injection system via its Features and Personnalities. Here's the big picture I got to:

That way, I believe that:

If I'm right, defining a Personnality will have App::Framework to load Features in specific folders first (hence the hierarchy I suggest).
Note: I couldn't find living examples of specifying the Personnality in the constructor, but documentation and source code seem to indicate that's the way I should call it.

For testing, I'm considering using Test::Class::Moose to structure my tests.

Questions

Thanks for your time!

  • Comment on Seeking opinion on a complete application framework, involving mocking and dependency injection
  • Select or Download Code

Replies are listed 'Best First'.
Re: Seeking opinion on a complete application framework, involving mocking and dependency injection
by 1nickt (Canon) on Mar 04, 2017 at 22:07 UTC

    Hi locinus, welcome to the Monastery and to Perl, the One True Religion.

    I can't comment on App::Framework as I'm not familiar with it; personally I prefer to build things up one brick at a time, but you may prefer an extensive scaffold. There's more than one way to do it.

    But I will comment on what I understand to be your plan to have your classes act differently depending on the environment, in order to be able to test your code: it smells fishy, and I don't think it is needed.

    See Test::MockObject - "Perl extension for emulating troublesome interfaces" ( and Test::MockObject::Extends ).

    Hope this helps!


    The way forward always starts with a minimal test.
      Hi! Thanks a lot for your reply!

      As for the testing part, I had checked those modules indeed, but had the following thoughts about them:

      • their use seem to be very sequential, where I would prefer an object approach
      • I will need some "common" mocked services to use with all my different tests, and I don't want to duplicate mocking codes for each test, even though I could factorize the mocking in some shared methods
      In the end, I can see this advantage of using Test::MockObject over using mocking by inheritance as I was suggesting:
      • gain ability to check the program's behaviour vis-a-vis the mocked class (via methods like call_pos, call_args, next_call, etc.)
      What other advantages would I gain?
      Is there any caveats at mocking by inheritance as I was suggesting?

      PS: oh, about your comment, I may have misused the word 'environnement' in my question: I didn't mean architecture environment but rather meant 'test situation' (I corrected it in the text).