<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Coding &#8211; Cognim &#8211; Internet development</title>
	<atom:link href="https://www.cognim.co.uk/tag/coding/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.cognim.co.uk</link>
	<description>Enterprise system implementation. Making the complex simple</description>
	<lastBuildDate>Wed, 26 Aug 2015 09:38:57 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
<site xmlns="com-wordpress:feed-additions:1">91553907</site>	<item>
		<title>Use Fluent Builders In Your Tests &#8211; C#</title>
		<link>https://www.cognim.co.uk/use-fluent-builders-in-your-tests/</link>
					<comments>https://www.cognim.co.uk/use-fluent-builders-in-your-tests/#comments</comments>
		
		<dc:creator><![CDATA[Darren Hall]]></dc:creator>
		<pubDate>Wed, 05 Aug 2015 16:22:04 +0000</pubDate>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Coding]]></category>
		<guid isPermaLink="false">http://www.cognim.co.uk/?p=5107</guid>

					<description><![CDATA[When creating tests (for TDD or BDD), use fluent builders No, I don&#8217;t mean the kind that come around and drink all your coffee / tea. When you are testing your code you often have to initialise various classes beforehand. There are several ways to do this. Consider this simple api that takes in a [&#8230;]]]></description>
										<content:encoded><![CDATA[<h3>When creating tests (for TDD or BDD), use fluent builders</h3>
<p>No, I don&#8217;t mean the kind that come around and drink all your coffee / tea. When you are testing your code you often have to initialise various classes beforehand. There are several ways to do this. Consider this simple api that takes in a &#8216;Booking&#8217; object and returns the cost of the booking.</p>
<pre class="">public int GetCostOfBooking(Booking booking)
{
    // ... implementation not important here
}</pre>
<p>Where the Booking object is</p>
<pre class="">public class Booking
{
    public DateTime FirstDay { get; set; }

    public DateTime LastDay { get; set; }

    public decimal LocationCostPerNight { get; set; }

    public Customer Customer { get; set; }
}</pre>
<p>and the Customer object is</p>
<pre class="">public class Customer
{
    public decimal PercentDiscount { get; set; }
}</pre>
<p>Your test could be set up as follows</p>
<pre class="">[TestMethod]
public void BookingCostIsCorrect()
{
    var customer = new Customer { PercentDiscount = 10 };
    var booking = new Booking
                      {
                          FirstDay = DateTime.Parse("2015/08/15"), 
                          LastDay = DateTime.Parse("2015/08/20"), 
                          LocationCostPerNight = 10, 
                          Customer = customer
                      };
    var actual = GetCostOfBooking(booking);
    var expected = 45;
    Assert.AreEqual(expected, actual);
}</pre>
<p>(please bear with me on these primitive samples and tests!)</p>
<p>Now this doesn&#8217;t look too bad, but what if I add more properties to Customer and Booking or force the use of constructors and specific set methods?</p>
<pre class="lang:c# decode:true">public class Booking
{
    public DateTime FirstDay { get; private set; }
    public DateTime LastDay { get; private set; }
    public decimal LocationCostPerDay { get; private set; }
    public Customer Customer { get; private set; }

    public void SetCostPerDay(decimal costPerDay)
    {
        this.LocationCostPerDay = costPerDay;
    }

    public void SetFirstDay(DateTime firstDay)
    {
        this.FirstDay = firstDay;
    }

    public void SetLastDay(DateTime lastDay)
    {
        this.LastDay = lastDay;
    }

    public void SetCustomer(Customer customer)
    {
        this.Customer = customer;
    }
}</pre>
<pre class="lang:c# decode:true">public class Customer
{
    public Customer(string firstName, string lastName, DiscountScheme discountScheme)
    {
        this.FirstName = firstName;
        this.LastName = LastName;
        this.DiscountScheme = discountScheme;
    }

    public string FirstName { get; private set; }

    public string LastName { get; private set; }

    public DiscountScheme DiscountScheme { get; private set; }
}</pre>
<pre class="lang:c# decode:true">public class DiscountScheme
{
    public decimal PercentDiscount { get; private set; }

    public void SetDiscount(decimal discount)
    {
        this.PercentDiscount = discount;
    }
}</pre>
<p>Now my test setup becomes</p>
<pre class="lang:c# decode:true">[TestMethod]
public void BookingCostIsCorrect()
{
     var discountScheme = new DiscountScheme();
     discountScheme.SetDiscount(10);
     var customer = new Customer("Johnny", "BigCheese", discountScheme);
     var booking = new Booking();
     booking.SetCustomer(customer);
     booking.SetFirstDay(DateTime.Parse("2015/08/15"));
     booking.SetLastDay(DateTime.Parse("2015/08/15"));
     booking.SetCostPerDay(10);
     var actual = GetCostOfBooking(booking);
     var expected = 45;
     Assert.AreEqual(expected, actual);
}</pre>
<p>Oh, not so nice any more. I have polluted my test with superfluous information, I am relying on calling the right methods to initialise properties and I have made the test that bit more obfuscated.</p>
<p>Instead, how about this</p>
<pre class="lang:c# decode:true ">[TestMethod]
public void BookingCostIsCorrect()
{
    var customer = new CustomerBuilder()
                        .WithDiscount(10);

    var booking = new BookingBuilder()
                        .FromFirstDay("2015/08/15")
                        .ToLastDay("2015/08/19")
                        .ForCustomer(customer)
                        .AtCostPerDay(10);

    var actual = GetCostOfBooking(booking);
    var expected = 45;
    Assert.AreEqual(expected, actual);
}</pre>
<p>Much nicer! It is easy to see what we are testing and how it is set up. There is no unnecessary information here. Also, thanks to the use of a builder, all the code for creating those objects is in a central place so you don&#8217;t have to edit all your tests when there is a change in how they should be initialised.</p>
<h3>Great!  How do I do it?</h3>
<p>It&#8217;s really not that difficult and once you have written a few you start to get the hang of it.  For instance here are the builder classes we have used above</p>
<pre class="lang:c# decode:true" title="BookingBuilder">public class BookingBuilder
{
    private Booking booking;

    public BookingBuilder()
    {
        this.booking = new Booking();
    }

    public static implicit operator Booking(BookingBuilder builder)
    {
        return builder.booking;
    }

    public BookingBuilder ForCustomer(Customer customer)
    {
        this.booking.SetCustomer(customer);
        return this;
    }

    public BookingBuilder FromFirstDay(string firstDay)
    {
        this.booking.SetFirstDay(DateTime.Parse(firstDay));
        return this;
    }

    public BookingBuilder ToLastDay(string lastDay)
    {
        this.booking.SetLastDay(DateTime.Parse(lastDay));
        return this;
    }

    public BookingBuilder AtCostPerDay(decimal costPerDay)
    {
        this.booking.SetCostPerDay(costPerDay);
        return this;
    }
}</pre>
<pre class="lang:c# decode:true" title="CustomerBuilder">public class CustomerBuilder
{
    private Customer customer;

    public CustomerBuilder()
    {
        this.customer = new Customer("Test", "Test", new DiscountScheme());
    }

    public static implicit operator Customer(CustomerBuilder builder)
    {
        return builder.customer;
    }

    public CustomerBuilder WithDiscount(decimal discount)
    {
        this.customer.DiscountScheme.SetDiscount(discount);
        return this;
    }
}</pre>
<p>The main thing to remember when creating a fluent builder is that your methods return the class itself, that allows you to chain them. Note also the static implicit operator that converts between the builder and the object it is building. Adding that means we can directly use the builder in place of the object being built (ie passing the booking builder into the GetCostOfBooking method.</p>
<p>I mean this blog to be an introduction to fluent builders &#8211; <a href="https://www.cognim.co.uk/going-further-with-fluent-builders-in-your-tests-c/">you can get much more fancy with them than this and I have written a blog here that shows how to do that</a>.</p>
<p>If you have any questions or want to add your own feedback, please comment below.  We would love to hear from you.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.cognim.co.uk/use-fluent-builders-in-your-tests/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">5107</post-id>	</item>
	</channel>
</rss>
