Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Wednesday, 16 May 2012

Why are interfaces important?

not a pattern.. a language feature.

time zone changes..

We want to give the current Date and Time as a dependency.. so can test properly eg

what if our licence never expires in following 5 years.. want to inject what would happen in the future,  and using DateTime.Now in our licence code means can’t test that.

[TestFixture]
  public class LicenceTests
  {
      [Test]
      public void HasExpired_AnExpiredDate_ReturnFalse()
      {
          Licence licence = new Licence(new DateTime(2000,1,1,0,0,0));
          Assert.IsTrue(licence.HasExpired);
      }

      [Test]
      public void HasExpired_AFutureDate_ReturnTrue()
      {
          Licence licence = new Licence(new DateTime(2020, 1, 1, 0, 0, 0));
          Assert.IsFalse(licence.HasExpired);
      }
  }

  class Licence
  {
      //field
      private readonly DateTime expirey;

      public Licence(DateTime expirey)
      {
          //expirey is a variable or local variable
          this.expirey = expirey;
      }

      //property
      public bool HasExpired
      {
          //a dependency on a static method
          //nothing we can do to make it behave differtly in tests  
          get { return DateTime.UtcNow > expirey; }
      }
  }

 

StubClock and SystemClock both implement IClock

public interface IClock
    {
        /// <summary>
        /// Gets the current <see cref="Instant"/> on the time line according to this clock.
        /// </summary>
        Instant Now { get; }
    }

so thats how this code uses interfaces.. for testing we’ve got a StubClock that we can set the time on.  For production we pass in the actual time.

[TestFixture]
public class LicenceTests
{
    [Test]
    public void HasExpired_AnExpiredDate_ReturnTrue()
    {
        Instant expirey = Instant.FromUtc(2000, 1, 1, 0, 0, 0);
        StubClock clock = new StubClock(expirey + Duration.FromTicks(1));

        //injecting the dependency
        Licence licence = new Licence(expirey, clock);

        Assert.IsTrue(licence.HasExpired);
    }

    [Test]
    public void HasExpired_AFutureDate_ReturnTrue()
    {
        Instant expirey = Instant.FromUtc(2000, 1, 1, 0, 0, 0);
        StubClock clock = new StubClock(expirey - Duration.FromTicks(1));

        Licence licence = new Licence(expirey, clock);

        Assert.IsFalse(licence.HasExpired);
    }

    [Test]
    public void HasExpired_AtExactInstant_ReturnTrue()
    {
        Instant expirey = Instant.FromUtc(2000, 1, 1, 0, 0, 0);
        StubClock clock = new StubClock(expirey);

        Licence licence = new Licence(expirey, clock);

        Assert.IsTrue(licence.HasExpired);
    }

    [Test]
    public void HasExpired_NonExpiredLicenceBecomesExpires_ReturnTrue()
    {
        Instant expirey = Instant.FromUtc(2000, 1, 1, 0, 0, 0);
        StubClock clock = new StubClock(expirey - Duration.FromTicks(1));

        Licence licence = new Licence(expirey, clock);

        Assert.IsFalse(licence.HasExpired);
        clock.AdvanceTicks(1);
        Assert.IsTrue(licence.HasExpired);
    }
}

class Licence
{
    private readonly Instant expirey;
    private readonly IClock clock;

    public Licence(Instant expirey, IClock clock)
    {
        //variables or local variables
        this.expirey = expirey;
        this.clock = clock;
    }

    //property
    public bool HasExpired
    {
        get { return clock.Now >= expirey; }
    }
}

public class BigApplicatiion
{
    static void Main ()
    {
        //a natural singleton!  there is only 1 system clock
        //but there is no way to test this business code...want dependency injection
        Licence licence = new Licence(Instant.FromUtc(2012,4,19,0,0), SystemClock.Instance);
        if (licence.HasExpired)
        {
            Console.WriteLine("Licence expired");
            return;
        }
    }
}
| | #