Can I use more than 4 parameters?

Jul 12, 2010 at 5:01 PM

Pararmeter support is fantastic but is there any way to use more than 4 parameters? I am getting the compile error "no overload for method 'When' takes '6' arguments, I think because the standard Action<T1 ... Tn> templates only support n up to 4.

Table support would be really great too for this kind of situation!


Jul 12, 2010 at 9:37 PM

You are correct and would need to update the arbitrary constraint in the code, re-run t4 template and recompile (this process is described elsewhere). The decision was made for four to keep the number of combinations low. You may have a good scenario for six but you may also have a scenario where keeping to the four may may the differences clearer.

This constraint is set in line 79:


       foreach(var exit in state.OutgoingTransitions)
           var target = exit.ToState;
           string prefix = CamelCaseToSentence(exit.Label.Name);
           if (IsExecutable(target))
79 -->         for(int i = 0; i < 5; i++)
                   var nums = Enumerable.Range(1, i);
                   string types = Join(", ", nums.Select(x=>"T"+x));
                       types = "<"+types+">";



Jul 13, 2010 at 5:47 AM

In addition to todd's post, you might need to create Action delegates that take enough arguments. In .NET 3.5, it only goes up to 4, which is why we only go up to 4. In .NET 4, you can go up to 16 - we're waiting for a wee while before we make StoryQ .NET 4-only, but you can go ahead and make the change that todd's suggested...


Cheers - Rob

Jul 13, 2010 at 3:16 PM

Thanks Todd & Rob.

The case for more than 4 was trying to do a more specification by example style test against a component where a message with specific properties had to be passed in. Rather than increase the number of parameters for now I have simply rewritten the test from a single line to something like this:

With Scenario Handling A Message
Given The Message Monitor Is Running
When A Message Is Received
And the message Property1 is {property1:prop1value}
And the message Property2 is {property2:prop2value}
And the message Property3 is {property3:prop3value}
And the message Property4 is {property4:prop4value}
And the message SentAtDate is {sentAtDate:2000-12-25 23:59:59}

Hopefully someone else will find this useful.


Jul 13, 2010 at 5:30 PM
Edited Jul 13, 2010 at 5:33 PM

Hi Alex

why don't you have your step method as:

WhenTheMessage_IsReceived(Message message)

As long as you override ToString on your message, or provide a ParameterFormat in your step method, it should look good when you run your tests

I forgot to mention, you can do table valued unit tests! Just pretend you're not using storyQ - use the normal MSTest / NUnit technique


Jul 15, 2010 at 12:01 PM

Thanks Rob. 

The ToString's not going to work too well for us but ParameterFormat might work well.

Do you mean extending the abstract ParameterFormatAttribute to handle our customer Message type such as:

class MessageParameterFormat : ParameterFormat
  public override string Format(object value)
    var message = value as Message;
    if (message == null)
       throw new InvalidArgumentException("MessageParameterFormat can only handle Message objects");

    return String.Format("Property1: {0} Property2: {1} SentAtDate: {3}",
           message.Property1, message.Property2, message.Property3);


Then used like:

WhenTheMessage_IsReceived([MessageParameterFormat] Message message)

On the Table valued tests do you have any links to examples of the usual technique with NUnit? My searches are turning blanks ):

Jul 15, 2010 at 1:48 PM
Yep - exactly Here's the only way i'm aware of with NUnit: