Topics covered:

  • Testable Code
  • Fakes, Mocks, Stubs
  • Mocking
  • Moq
  • JustMock

Video (in Bulgarian)

Presentation Content

How to Write Testable Code

  • Inversion of Control Pattern
    • There is a decoupling of the execution of a certain task from implementation
    • Every module can focus on what it is designed for
    • Modules make no assumptions about what other systems do but rely on their contracts
    • Replacing modules has no side effect on other modules
    • More info at http://en.wikipedia.org/wiki/Inversion_of_control

How to Write Testable Code

  • Public API should work with interfaces, not implementation classes (IEnumerable vs. List)
  • Bad code:
public Card[] Cards { get; private set; }
  • Good code:
public IList<ICard> Cards { get; private set; }

Dependency Injection

  • IoC Containers
  • Consists of:
    • A dependent consumer
    • A declaration of a component’s dependencies, defined as interface contracts
    • An injector (sometimes referred to as a provider or container) that creates instances of classes that implement a given dependency interface on request

How to Write Testable Code

  • Bad:
public interface IViewBase {}
public interface IPresenterBase {}
public class MemoryLayoutView: IViewBase {}

public class MemoryLayoutPresenter: IPresenterBase
{
    private MemoryLayoutView view = new MemoryLayoutView();
    public MemoryLayoutPresenter() { }
}

How to Write Testable Code

  • Good:
public interface IViewBase {}
public interface IPresenterBase {}
public class MemoryLayoutView: IViewBase {}
public class MemoryLayoutPresenter : IPresenterBase
{
  private IViewBase view;
  public MemoryLayoutPresenter(IViewBase myView) 
  {
    this.view = myView;
  }
}
public class Program {
  static void Main() {
    InjectionContainer.Create<typeof(MemoryLayoutPresenter)>();
  }
}

Faking

  • Makes Unit Testing more effective
    • Avoid writing boring boilerplate code
  • Isolate dependencies among units
  • Asserts expectations for code quality
    • Ex: Checks that a method is called only once

Fake vs Mock vs Stub

  • Fake - objects actually have working implementations but with limited capabilities.
  • Stub - provide canned answers to calls made during the test. May record information about calls.
  • Mock - objects pre-programemd with expectations against we can assert

Mocking

  • You can use inheritance to replace logic
    • Maintainability - hard to achieve it
    • Gets really complicated
    • Could lead to errors
  • Could create fake objects
  • Set the desired behaviour of the objects
  • Verify (Assert) against the fake objects
  • Constrained frameworks usually work by generating code at runtime that inherits and overrides interfaces or base classes
  • In .NET, constrained frameworks are unable to fake:
    • static methods
    • nonvirtual methods
    • nonpublic methods
    • and more
  • Unconstrained frameworks could be used as constrained as well
  • Using unconstrained isolation frameworks has some advantage
    • You can write unit tests for previously untestable code
    • You can fake third-party systems that you can’t control
    • If you don’t pay close attention, some tests can become unmaintainable

Moq

Moq syntax

  • The most often used APIs:
    • .Setup()
    • .Verifiable()
    • .Callback()
    • .Returns()
    • .Throws()
    • It.Is<type>(x => condition)

JustMock

  • Use the Visual Studio NuGet package manager
  • Two versions:
    • Free version (constrained)
    • Paid version (unconstrained)

JustMock syntax

  • The most often used APIs:
    • .CallOriginal()
    • .Returns()
    • .DoInstead()
    • .DoNothing()
    • .Throw()
    • Arg.Matches<type>(x => condition)
  • Constrained
    • FakeItEasy
    • nSubstitute
    • RhinoMocks
  • Unconstrained
    • Isolator
    • MS Fakes