Tuesday, January 26, 2010

|FitNesse in |flow| mode|

This is a brown-bag session we had at work. The objective was to show fitnesse beyond the ubiquitous column and row fixtures. It's heavily inspired by Gojko's "FitNesse.NET Tips and Tricks".

Here are the slides and the code.

 

Sunday, December 20, 2009

Longer case in favor of setter injection

The motive of this post is not to prove that setter injection is better than constructor injection. But being setter the underdog I am surprised how much it has helped in defining my style of development. So despite agreeing that is safer to always create a sound object, I get to write less production code and more expressive tests with the setter strategy.

The previous post laid the ground rules and general ideas behind why setter injection has simplified my code. Looking into Fubu MVC's code I found a nice example to illustrate what I mean. It's kinda funny because it was a post by Jeremy Miller what inspired me to look into Fubu's implementation. In that post he evens jokes about Chad using setter injection.

Here is the Test




[TestFixture]
public class
execute_one_in_one_out : InteractionContext<OneInOneOutActionInvoker<ITargetController, Input, Output>>
{
    private
Input theInput;
    private
Output expectedOutput;


    protected override void
beforeEach()
    {
        
Func<ITargetController, Input, Output> func = (c, i) => c.OneInOneOut(i);

        
Services.Inject(func);

        
theInput = new Input();
        
expectedOutput = new Output();

        
MockFor<IFubuRequest>().Expect(x => x.Get<Input>()).Return(theInput);
        
MockFor<ITargetController>().Expect(x => x.OneInOneOut(theInput)).Return(expectedOutput);

        
ClassUnderTest.Invoke();
    }

    [
Test]
    public void
should_have_stored_the_resulting_data_in_the_fubu_request()
    {
        
MockFor<IFubuRequest>().AssertWasCalled(x => x.Set(expectedOutput));
    }

    [
Test]
    public void
should_invoke_the_controller_method()
    {
        
VerifyCallsFor<ITargetController>();
    }
}




and the Code




public class OneInOneOutActionInvoker<TController, TInput, TOutput> : BasicBehavior where TInput : class
                                                                                    where
TOutput : class
{
    private readonly
Func<TController, TInput, TOutput> _action;
    private readonly
TController _controller;
    private readonly
IFubuRequest _request;
    
    public
OneInOneOutActionInvoker(IFubuRequest request, TController controller,
                                    
Func<TController, TInput, TOutput> action)
    {
        
_request = request;
        
_controller = controller;
        
_action = action;
    }

    
// TODO:  Harden against failures?
    protected override DoNext performInvoke()
    {
        var
input = _request.Get<TInput>();
        
TOutput output = _action(_controller, input);
        
_request.Set(output);

        return
DoNext.Continue;
    }
\




Here is how I would write Test




[TestFixture]
public class
when_executing_one_in_one_out : BehaviorOf<OneInOneOutActionInvokerWithSetters<ITargetController, Input, Output>> {
    
    [
Test]
    public void
should_have_stored_the_resulting_data_in_the_fubu_request() {
        var
Input = new Input();
        var
Output = new Output();
        
        
Given.Action = (c, i) => c.OneInOneOut(i);
        
Given.Request.Get<Input>().Is(Input);
        
Given.Controller.OneInOneOut(Input).Is(Output);
        
        
When.PerformInvoke();
        
        
Then.Request.Should().Set(Output);
    }
}




and the Code




public class OneInOneOutActionInvokerWithSetters<TController, TInput, TOutput> : BasicBehavior
    where
TInput : class where TOutput : class {
    
    public
Func<TController, TInput, TOutput> Action { get; set; }
    public
TController Controller { get; set; }
    public
IFubuRequest Request { get; set; }
    
    public override
DoNext PerformInvoke() {
        var
Input = Request.Get<TInput>();
        var
Output = Action(Controller, Input);
        
        
Request.Set(Output);

        return
DoNext.Continue;
    }
\




In both cases the TextFixture inherits from a base class. This is the Testcase Superclass pattern from Meszaros book. The idea is to establish a context for the SUT and simplify DI and mocking. In Fubu, InteractionContext provides a facade around Rhino Mocks enabling automocking and simplifying expectations calls. It also wraps the SUT with ClassUnderTest.

In my case BehaviorOf is the same pattern built into FluentSpec. The SUT dependencies are automocked and the SUT is wrapped. But instead of accessing the SUT through ClassUnderTest it's accessed through Given/When/Then connectors. As a result I would not need to implement InteractionContext.

Fubu's test was refactored into a common setup pattern which enables to have a single line per test and that line is an assertion. That is test nirvana. However the second test case does a VerifyCallsFor<TestDouble> which is a test smell. Therefore my test has a single assertion and there was no point in refactoring to common setup.

Because of the public dependencies instead of.




Func<ITargetController, Input, Output> func = (c, i) => c.OneInOneOut(i);

Services.Inject(func);
MockFor<IFubuRequest>().Expect(x => x.Get<Input>()).Return(theInput);
MockFor<ITargetController>().Expect(x => x.OneInOneOut(theInput)).Return(expectedOutput);

MockFor<IFubuRequest>().AssertWasCalled(x => x.Set(expectedOutput));




I can write.




Given.Action = (c, i) => c.OneInOneOut(i);
Given.Request.Get<Input>().Is(Input);
Given.Controller.OneInOneOut(Input).Is(Output);

Then.Request.Should().Set(Output);




Which is simpler, more expressive and no lambdas or brackets were harmed in vain. Also notice how clear is the separation between the test steps Setup/Exercise/Verify mapped to Given/When/Then than with the AAA syntax.

The Exercise step changed from ClassUnderTest.Invoke() to When.PerformInvoke(). In this case When is a win over ClassUnderTest but making PerformInvoke public is a loss. The tradeoff in my case boils down to focus. I want to exercise the essential amount of code related to the behavior being tested. So calling Invoke goes through different path of the code that I don't care while defining when_executing_one_in_one_out.

VerifyCallsFor<ITargetController> was not needed because it is ensuring that the expectations were executed for ITargetController. In this case MockFor<ITargetController>().Expect(x => x.OneInOneOut(theInput)).Return(expectedOutput) is a query. That happens mostly as a misuse of AAA syntax with Query/Command. Queries belong to the setup step and it feels silly to check AssertWasCalled on a query statement.

Queries can be verified either by checking affected state in the SUT, via the return value in a delegated query or because their result becomes an arg in a command call. We don't need to verify that Controller.OneInOneOut(Input) occurred because that is what ensures that Then.Request.Should().Set(Output) Given.Controller.OneInOneOut(Input).Is(Output).

Encapsulation is one of the fundamental concepts that makes OOP work. Sadly, it reinforces the human feeling of protection. And we do the most silly things in the name of protection. By letting go on class encapsulation in favor of abstract dependencies I have developed a style that leads to cleaner tests. Setter injection has opened the opportunity for the dependencies to join fluently in the chain of specifications.

I'd rather have everything but that's impossible. The tradeoffs you make are related to your personality. Because I favor expressiveness a lot more than security I was able to suspend beliefs and let go. I am much happier with more expressive tests than with the security that constructor injection offers. But that's me, you have your own rules to make, break and follow.

Thursday, November 26, 2009

Small case in favor of setter injection

In general setter injection is frowned upon. The main reason is mostly that an object should have all its dependencies at the creation time. That is very reasonable, but I find it a tad on the paranoid side. Or better put, I have been using setter injection only and have not found any problem ever. Furthermore, by having setter injection my objects and test code has remained cleaner than the alternative options.

Here are the rules

  • Depend only on interfaces
  • Don't use new
  • Don't define constructors in the class

Depending always on interfaces sounds extremist. But it happens naturally if a system is developed outside-in mocking the dependencies. The principal advantage of mocking is increased focus at the time of writing the code, the decoupledness is a side effect. Another side effect is that the interface becomes the public interface of the class.

Therefore making things public in the class doesn't break encapsulation. I do confess that having more public and virtual elements in the class obscures the understanding of what the class offers. But the interface is right there and it's easy to see what the class is exposing to others thru it.

Depending only on interfaces needs to be accompanied by forbidding the use of new. If an object has a dependency say "Command ToSave;" and does "ToSave = new SaveCommand();" to create it. The class would have a dependency on both the interface Command and the class SaveCommand.

Once new is forbidden there are two ways to create a class, either by having a factory object or by using a DI framework. Both approaches would lead to the decision of setter injection vs constructor injection. I chose setter because the class ends up cleaner that way by not needing constructor logic.

There's no way of generating an object on an unstable state because the dependencies are either injected by a framework or they had to be passed as args to the factory method. There's a backdoor to the object via new but it is simply forbidden and conveniently available to the test code.

The test code becomes simpler because we need to mock only the dependencies involved on a particular behavior. It is a smell to have multiple dependencies and only some of them needed at a given time but it happens. Even if it's only at some stage before the object is refactored into a better design.