Skip to content

Fake It Easy

Vijaya Venu edited this page Jul 19, 2018 · 5 revisions
  • Donald Belcham and Jim Cooper
  • Easy mocking library for .Net framework
    • A framework for creating all types of fake objects (mocks, stubs, etc..)
  • Easily readable
  • Package Manager Console Install-Package FakeItEasy
  • https://fakeiteasy.github.io/
  • Github
  • Key Points of a Good Unit Test:
    • Atomic
    • Deterministic
    • Repeatable
    • Order Independent & Isolated
    • Fast
    • Easy to Setup
  • Hand rolled mock objects. Creating mock classes and using them (no third party mock framework)
  • Fake v/s Mock v/s Stub
    • No distinction between the three when defining the object
    • Object usage determines if it is a Fake or Mock or Stub
  • Supports .Net 4.0 or higher
  • No support for Sealed, Static, Private only Constructor Class, private methods
  • Creating Fakes : There are several restrictions in creating Fake Objects

Examples

  • Faking
A.Fake<T>();
var fake = new Fake<IFoo>();
A.CollectionOfFake<T>(10);

// Create wrapper - unconfigured calls will be forwarded to wrapped
var wrapped = new FooClass("foo", "bar");
var foo = A.Fake<IFoo>(x => x.Wrapping(wrapped));
  • AAA
    • Arrange
      • Creating a fake object
      • Pass the fake to SUT (System Under Test)
    • Act
      • Execute the SUT
    • Assert
      • Verify SUT's interaction with the fake object
    • Code Example
    //Arrange
    var fakeRepository = A.Fake<ICustomerRepository>();
    var service = new CustomerService(fakeRepository);
    
    //Act
    service.Create(new CustomerDto());
    
    //Assert
    A.CallTo(
          () => fakerepository.Save<>(A<Customer>.Ignored))    //Interesting
          .MustHaveHappened();
    
  • Method Call Count Examples
MustHaveHappened(Repeated.Atleast.Once)
MustHaveHappened(Repeated.Exactly.Twice)
MustHaveHappened(Repeated.Exactly.Times(6))
MustHaveHappened(Repeated.NoMoreThan.Once)
MustHaveHappened(Repeated.Never)
MustNotHaveHappened()
  • When there is no need of assertion inside a Test Method?
    • When an [ExpectedException] attribute is set above the test method
  • Returns
A.CallTo(() => fakeObject.Method(A<ParamType>.Ignored)).Returns(FakeValue);
  • Out & Ref Parameter
// Code
var mailingAddressSuccessfullyCreated = mailingAddressFactory.TryParse(customer.Address, out MailingAddress, out doorNo)


// Test Code
MailingAddress returnedMailingAddress;
int returnedDoorNo;
A.CallTo(
  () => fakeMailingAddressFactory.Tryparse(
    A.Fake<String>.Ignored, out returnedMailingAddress, out returnedDoorNo))
  .Returns(true)
  .AssignsOutAndRefParameters(new MailingAddress(), 1052);
  • Return Different Value in a Loop
// Code
for {
  customer.Id = _idFactory.Create();
}

// Test
A.CallTo(
  () => fakeidFactory.Create())
  .ReturnsNextFromSequence(1, 2, 3, 4, 5);
  • Arguments A<T>.Ignored | A<T>.That...
// Code
GetFullName(firstName, lastName)
{
  var fullName = firstName + " " + lastName;
  return fullName;
}

// Test
A.CallTo(
  () => fakeFullNameBuilder.GetFullName("S", "Kota"))
  .MustHaveHappened();

A.CallTo(
  () => fakeFullNameBuilder.GetFullName(A<string>.That.Matches(s=>s.Equals("s")), "Kota"))
  .MustHaveHappened();
  • Exceptions
// Arrange
A.CallTo(
  ()=> fakeObject.fakeMethod(A<T>.Ignored))
  .Throws(new CustomException());

// Assert
//Check for Logging, re-thrown etc..
  • Properties
    • Setters
    Assert.That(fakeCustomRepository.FullName, Is.Not.Empty);
    Assert.That(fakeCustomRepository.FullName, Is.Not.Null);
    
    • Getters
    A.CallTo(() => fakeID.Age)MustHaveHappened();
    
    • Auto Mocking Hierarchies
    // Code
    var workStationId = _applicationSettings.SystemConfiguration.AuditingInformation.WorkStationId;
    
    // Test
    // Arrange
    A.CallTo(() => 
           fakeApplicationSettings
           .SystemConfiguration
           .AuditingInformation
           .WorkStationId)
     .Returns(5);
    // Assert
    A.CallTo(() => 
           fakeApplicationSettings
           .SystemConfiguration
           .AuditingInformation
           .WorkStationId)
     .MustHaveHappened();
    
  • Events
//Code
_customerRepository.NotifySalesTeam += NotifySalesTeam;
NotifySalesTeam(sender, NotifySalesTeamEventArgs e);

//Test
// Act
fakeCustomerRepository.NotifySalesTeam +=
  Raise.With(new NotifySalesTeamEventArgs())
    .Now;
  • Ordered Assertions
fake.CreateScope();
scope.OrderedAssertions();

Advanced Faking

  • Strict & Loose Mocking
    • Strict: Raises exception for anything on a mock object that doesn't have an explicitly declared expectation
    • Loose: No exception raised. Returns Default Values when no exception is explicitly declared.
    • Fake It Easy will not create Strict Objects
  • Protected Members. MethodName is hardcoded in string format
    A.CallTo(fakeRepository)    //returns fakeObject
      .Where(x => x.Method.Name == "ProtectedMethodName")    //reference of protected method returned.
    
  • No Intellisense

Clone this wiki locally