tags:

views:

646

answers:

2

I've got a Fitnesse RowFixture that returns a list of business objects. The object has a field which is a float representing a percentage between 0 and 1. The consumer of the business object will be a web page or report that comes from a designer, so the formatting of the percentage will be up to the designer rather than the business object.

It would be nicer if the page could emulate the designer when converting the number to a percentage, i.e. instead of displaying 0.5, it should display 50%. But I'd rather not pollute the business object with the display code. Is there a way to specify a format string in the RowFixture?

A: 

I'm not sure what the "polution" is. Either the requirement is that your Business Object returns a value expressed as a percentage, in which case your business object should offer that -OR- you are testing the true value of the response as float, which you have now.

Trying to get fitnesse to massage the value for readability seems a bit odd.

Tom Carr
+2  A: 

You certainly don't want to modify your Business Logic just to make your tests look better. Good news however, there is a way to accomplish this that is not difficult, but not as easy as passing in a format specifier.

Try to think of your Fit Fixture as a service boundary between FitNesse and your application code. You want to define a contract that doesn't necessarily have to change if the implementation details of your SUT (System Under Test) change.

Lets look at a simplified version of your Business Object:

public class BusinessObject
{
 public float Percent { get; private set; }
}

Becuase of the way that a RowFixture works we need to define a simple object that will work as the contract. Ordinarily we would use an interface, but that isn't going to serve our purpose here so a simple DTO (Data Transfer Object) will suffice.

Something Like This:

public class ReturnRowDTO
{
 public String Percent { get; set; }
}

Now we can define a RowFixture that will return a list of our custom DTO objects. We also need to create a way to convert BusinessObjects to ReturnRowDTOs. We end up with a Fixture that looks something like this.

public class ExampleRowFixture: fit.RowFixture
    {
     private ISomeService _someService;

     public override object[] Query()
     {
      BusinessObject[] list = _someService.GetBusinessObjects();

      return Array.ConvertAll(list, new Converter<BusinessObject, ReturnRowDTO>(ConvertBusinessObjectToDTO));
     }

     public override Type GetTargetClass()
     {
      return typeof (ReturnRowDTO);
     }

     public ReturnRowDTO ConvertBusinessObjectToDTO(BusinessObject businessObject)
     {
      return new ReturnRowDTO() {Percent = businessObject.Percent.ToString("%")};
     }
    }

You can now change your underlying BusinessObjects around without breaking your actual Fit Tests. Hope this helps.

Josh