Justin Saret’s incongruous thoughts

What’s been playing on my mind lately is…

Unit Testing object parameters using Rhino Mock Constraints

Posted by saret on October 6, 2007

Normally when unit testing and using a mock framework like Rhino one tests the interaction style of the method under test with it’s dependencies by generating mocks with Rhino in our code. This allows testing that the mock dependencies’ methods were used as we expect them to be, however testing the object passed to the mock as a parameter is often necessary. This often happens when the method under test either has to construct the object, the object is passed into the method or obtained from another mocked dependency such as a repository and especially when the objected (however it gets into the class under test) is changed prior to being passed as a parameter.

Rhino mocks offers a couple of ways that allow us to do this. Which method you should use often depends on your requirements on how you need to test the parameter.

This example (don’t judge it’s architecture/code as it’s just that - an example, that might not compile as this post was done in a text editor) concerns a controller that sends a generic email message to a list of addresses. For simplicity I’ve ignore any view or email address object, which would require more code to show a proper test for this example as well as null/empty checks on parameters. In this example I’ll be passing the data directly into a method of the email controller, then constructing an email message object (forgetting that email address might be an object) and passing it to a email sender interface (mocked).

The actual code might be roughly like this:

public class EmailController
{
    private IEmailGateway _gateway;

    public EmailController(IEmailGateway gateway)
    {
        _gateway = gateway;
    }

    public void SendMessageToRecipients(IList emailAddresses, string message)
    {
        EmailMessage message = new EmailMessage(emailAddresses, message);
        _gateway.SendEmail(message);
    }
}

Probally easiest way to test the parameter passed is when you can construct and compare an EmailMessage in your test. This would lead to test code such as this:

[Test]
public void TestThatMyMethodPassesTheRightData()
{
    List recipients = { “bob@x.com, james@y.com, peter@p.com”};
    string message = “This is auto generated”;
    EmailMessage expectedMessage = new EmailMessage(recipients, message);
    
    MockRespository mockRepo = new MockRepository();
    IEmailGateway gateway = mockRepo.CreateMock();
    
    EmailController testController = new EmailController(gateway);
    
    using(mockRepo.Record())
    {
        gateway.SendEmail(null);
        LastCall.Constraint(Is.Equal(expectedMessage));
    }
    using(mockRepo.PlayBack())
    {
        testController.SendMessageToRecipients(recipients, message);
    }
}

Sometimes though one isn’t able to directly compare an object using the Equals method as the passed object might be different on every construction (even though the constructor parameters are the same). For example this can occur due to possibly autogenerated numbers/Guids in the passed objects constructor.
In this case, one needs to be able to test the object’s state such as via it’s properties. While there are a couple of ways of doing this, one way I tend to use is like this:

[Test]
public void TestThatMyMethodPassesTheRightData()
{
    List recipients = { “bob@x.com, james@y.com, peter@p.com”};
    string message = “This is auto generated”;

    Predicate constraint = delegate(EmailMessage msg)(
        { return (msg.Recipients == recipients) && (msg.Message == message); });
    
    MockRespository mockRepo = new MockRepository();
    IEmailGateway gateway = mockRepo.CreateMock();
    
    EmailController testController = new EmailController(gateway);
    
    using(mockRepo.Record())
    {
        gateway.SendEmail(null);
        LastCall.Constraint(Is.Matching(constraint));
    }
    using(mockRepo.PlayBack())
    {
        testController.SendMessageToRecipients(recipients, message);
    }    
}

This technique utilizes an anonymous delegate/closure so one can keep the declaration of the predicate within the test method itself. While this is shown using c# 2, the code is even more compact/cleaner using some other languages such as c# 3’s lambda expressions, or Boo’s closure syntax. for example in Boo one can write the predicate like this:

constraint = {msg as EmailMessage | msg.Recipients == recipients && msg.Message == message}

Sometimes though one might need to test multiple calls to a mocked dependancy, with each call having a different parameter.
If the EmailController’s method’s was writing like the following code then this would be the case

public void SendMessageToRecipients(IList emailAddresses, string message)
{
    foreach(string recipient in emailAddresses)
    {
        EmailMessage message = new EmailMessage(recipient, message);
        _gateway.SendEmail(message);
    }
}

For the following I’m assuming that one would be interested in testing this in an ordered manner, even though in reality one probally wouldn’t be that interested in the order of calls for this method.
The test method for equals would look like this:

[Test]
public void TestThatMyMethodPassesTheRightData()
{
    List recipients = { “bob@x.com, james@y.com, peter@p.com”};
    string message = “This is auto generated”;
    EmailMessage expectedMessage1 = new EmailMessage(”bob@x.com”, message);
    EmailMessage expectedMessage2 = new EmailMessage(”james@y.com”, message);
    EmailMessage expectedMessage3 = new EmailMessage(”peter@p.com”, message);
    
    MockRespository mockRepo = new MockRepository();
    IEmailGateway gateway = mockRepo.CreateMock();
    
    EmailController testController = new EmailController(gateway);
    
    using(mockRepo.Record())
    {
        using(mockRepo.Ordered())
        {
            gateway.SendEmail(null);
            LastCall.Constraint(Is.Equal(expectedMessage1));
            
            gateway.SendEmail(null);
            LastCall.Constraint(Is.Equal(expectedMessage2));
            
            gateway.SendEmail(null);
            LastCall.Constraint(Is.Equal(expectedMessage3));
        }
    }
    using(mockRepo.PlayBack())
    {
        testController.SendMessageToRecipients(recipients, message);
    }
}

The code can also be wrapped up in a loop if required within the ordered area (using a List to store the expected messages).

If however we can’t use the Equals constraint, one could do this using the predicate option. While one can just define multiple
predicates for this purpose, one technique I’ve been using in my newest pet project (built using Boo) is to define the preditate
once, but use currying to vary it for each constraint such as like this:

delegate Predicate constraint(string address);
[Test]
public void TestThatMyMethodPassesTheRightData()
{
    List recipients = { “bob@x.com, james@y.com, peter@p.com”};
    string message = “This is auto generated”;

    Constraint constraint = delegate(string address)(
        {
            return delegate(EmailMessage msg)
                {
                    return (msg.Recipients == address) && (msg.Message == message);
                };
        });
        
    MockRespository mockRepo = new MockRepository();
    IEmailGateway gateway = mockRepo.CreateMock();
    
    EmailController testController = new EmailController(gateway);
    
    using(mockRepo.Record())
    {
        using(mockRepo.Ordered())
            {
                gateway.SendEmail(null);
                LastCall.Constraint(Is.Matching(constraint(recipients[0])));
                
                gateway.SendEmail(null);
                LastCall.Constraint(Is.Matching(constraint(recipients[1])));
                
                gateway.SendEmail(null);
                LastCall.Constraint(Is.Matching(constraint(recipients[2])));
            }
    }
    using(mockRepo.PlayBack())
    {
        testController.SendMessageToRecipients(recipients, message);
    }    
}

Again this looks alot better using Boo’s syntax. The constraint could be defined like this without the delegate definition:

constraint = def(address):
    return {msg as EmailMessage | msg.Recipient == address & msg.Message == message }

This technique also allows you to wrap all the expected and lastcall lines up in a loop if required.
Jeffrey Palermo presents another method on doing this that I found before finishing this post.

Posted in .NET, Boo, Testing, c# | No Comments »

The high cost of function calls … and dangerous missinformation

Posted by saret on July 20, 2007

Please excuse the relatively long post as I haven’t gotten into the rhythm of blogging yet and unfortunately I didn’t really take too much notice of those writing lessons back in school and university (inference trees for logically correct argumentative writing layout etc… - the lecturer was a clever guy but his lecturing style just didn’t seem to hold me). Hopefully my writing style will improve – which is one of the reasons I decided to start blogging a couple years ago.., and the length of the articles will too (code fragments aside).

Over the last month I’ve been doing extra contracting to a firm (who seem to be relatively jacked up in the interactive media and video space and are trying out various concepts), devoting any of my extra spare work time to them. They were partly desperate for someone to change/fix some of the mobile web app they had developed with company x who are involved in the project but couldn’t seem to find the time to change the app.

I had not really used PHP before (a little messing around a couple of years before doesn’t count), so I definitely haven’t been working on the project at a more productive rate/velocity and my cadence (rhythm so to speak) has been off due to the initial learning curve (still have to lookup common global functions often…). Personally I feel that I probably should not have taken on the work due to a lesser ability to deliver value in a shorter time frame/box due to that, but the work load seemed pretty trivial so I did the guy who contracted me (I know him from school but hadn’t seen him in many years) a favour and helped with this project.

Now according to the definition of legacy systems/code given by the Poppendiecks (”There are two kinds of software - change tolerant software and legacy software… we can define legacy systems as systems that are not protected with a suite of tests”) this app, no matter how small it currently is, can be called a legacy application.

Personally I fall into the OO camp in development practice/programming (quick scripts usually not) and choose to work with objects (classes) when I can, be this in c#/java/eiffel/python …, but back in some of my vb (5-6) days though, I normally didn’t – I was often the only person doing the programming and while I did structure the app logically (at least to my mind back then on what a layered app should look like). While this doesn’t mean that I think procedural code is inherently bad - as long as it has tests backing it up then it’s quality can be on an equal level – but the ability to maintain the app and more easily extend it (polymorphism / new functionality) and refactor it to a cleaner code base (at least in my eyes) is usually diminished in procedural code. This PHP webapp it turns out is procedural all the way.

A couple of days ago I went into the company [x] who originally developed the “framework/core” of this system to work on this project due to issues once it was deployed and was surprised/even shocked at how these guys were working. Now these guys aren’t stupid –they been in the it space longer than me, however they still seem to be sitting on a wealth of invalid/incorrect knowledge regarding software development. They don’t do any automated testing, not in this app or (from what I gather) even in their core framework for their WASP system - according to their “resident geek” you just need to run it and see if it works…

While I’m not a best practices nazi, I still believe in doing things “right” given the chance but was in essence told “automated testing would serve no purpose” and not to do it. Even more confounding was the fact that they don’t utilize some form of source control. While I’ve been to smaller Dev shops/companies that also don’t utilize any sort of source control (and often don’t even know what it is), these guys, from what I gather, know about source control but basically see no point in a source control system (at least for work they do for partnerships/clients, unless they have just “abstracted me from it” – in which case I’m probably working off a stale code base).

The real killer though was when I mentioned to the “chief geek” that I needed a function/Regex to validate a variable and that I wished to move his inline regex in the middle of some function to a central point (maybe global function file called validation or something). Suddenly the guy started ranting about the idea of doing this and crapping on me as if I was committing a cardinal sin just shy of murder. He told me I should copy and paste the regex wherever I needed it, even though in my one method I needed to do it on three variables. According to him the cost of calling a method is too high.

While the cost of a function call might be high in PHP, I don’t believe that sub-optimization below the method level (ie at the compiler/interpreter level by manually inlining code - to the expense/detriment of good architecture and easier to understand and maintain code) makes any sense in an application that hasn’t even put anything near the stress level the server can handle, or had any benchmarking/performance testing done on it.

I personally don’t believe that performance should be an end stage in a development process, that is, one should be wary of bad performing code from the inception of the project – if one can build a O(N log N) sort/search function instead of a 0(n^2) algorithm then performance of that function will be better, but if the function only needs to ever work on a tiny data list of 5 entities then the performance gains will be minimal. This is why one should never try performance optimizations without doing some form of profiling; chances are the exact areas that are bad performing are not where you think they are. I personally believe that good architected code allows one to do performance tweaking far easier as the changes that need to be performed are often done internally in methods that allow one to make big changes while abstracting the rest of the code base from those changes – plus having a test suite to back you up to make sure the code still does what you expect it to do is invaluable.

I would venture so far as to say that for the 99.99% (maybe even higher) of all programmers out there the less than one millisecond overhead for a function doesn’t matter and shouldn’t be worried about – if fact calling the regex 3 times directly in a loop vs calling it though a method in the same loop has less than a millisecond difference on my pc. The .01% of programmers who actually should worry about it are the guys actually building compilers/interpreters/executor engines or really heavy optimized code such as large statistical analysis of massive input data. For anyone else the data access code/remote call in the same method will probably take up the bulk of the execution time of the function and adding a little method call will be negligible in comparison.

If regular method dispatch overhead is something to be worried about, I would question the environment/language that you are using – why use PHP when assembler/C can be used?

What they don’t seem to understand is that using caching would be where they would really achieve performance gains – both caching of the data/pages the app uses and utilizing a opcode cache mechanism so the PHP engine doesn’t have to do repeated interpreting of you code.

Achieving better performance isn’t done by minor sub-optimizations that turn you code into a big ball of mud!

Ultimately what should be the aim of both me and company [x] is to provide value to this application by building both new functionality and building a solid code base that is tested. Them not giving me feedback from the live environment (they have no testing environment for me to utilize so the stored procedure that “happens to send out an sms” can’t be tested by me) just makes it harder and more frustrating for me to do what I need to do and is doing the company I’m doing it for (company x’s partners) a huge disservice.
When disparate teams/individuals work together, they should make it a priority to build synergy between the teams - which often can only happen when both sides realize that they themselves might be a part of the problem in the value/production/process chain and actively work to address the issues. By having to wait not just for the code to be deployed, but also for any feedbank (i.e. error catching) I am not able to move forward leading to excess waste (lost time).

While I still have much to say about stored procedures and these guy’s utilization of them (my guess is there is a system service polling the sms table not a trigger – I don’t have the relevant database so not sure), as well as their’s/others’ invalid knowledge/opinions about other languages and why language wars are pointless (mostly people don’t know nearly enough about the other language/runtime they criticize, let alone their own, to speak authoritatively about why their chosen language is better than another), but this will have to wait for another post as it’s really late here and need to be up early.

To finish off here’s some of my favourite quotes that help express some of what I believe and am trying to make a point of:

“It ain’t what you don’t know that gets you into trouble. It’s what you know for sure that just ain’t so.” - Mark Twain

“Beware of false knowledge; it is more dangerous than ignorance.” - George Bernard Shaw

“No man is so foolish but he may sometimes give another good counsel, and no man so wise that he may not easily err if he takes no other counsel than his own. He that is taught only by himself has a fool for a master.” -Hunter S. Thompson

Proverbs are always platitudes until you have personally experienced the truth of them” - Aldous Huxley

 

Posted in Architecture & Patterns, PHP, Possibly sane thoughts, Programming | No Comments »

echo Hello world!

Posted by saret on July 16, 2007

Thought I’d leave the title as it’s often the first place some of us start …

I’ve been meaning to start a blog for ages but never was able to  get round to it … finally thought I’d take the plunge now.

Bear with me while I’m still learning/setting things up…

Posted in Uncategorized | No Comments »