Giter VIP home page Giter VIP logo

fluentarrange's Introduction

dotnet-dash

FluentArrange lets you write clean Arrange blocks in your unit tests even when the constructor of the class under test has a lot of (mocked) dependencies.

Packages

Package Version Description
FluentArrange Nuget version Core package
FluentArrange.NSubstitute Nuget version When you use NSubstitute for mocking

Auto-Mocking Ctor Dependencies

Consider the following example where we use NSubstitute to mock dependencies:

var sut = new ResetPasswordController(
    Substitute.For<IAccountService>(),
    Substitute.For<IAuditService>(),
    Substitute.For<IMailService>());

With FluentArrange, an instance T is instantiated using Arrange.Sut<T>, and all of its constructor dependencies are auto-mocked:

var sut = Arrange.Sut<ResetPasswordController>();

Adding new dependencies will not break existing unit tests.

Arranging Dependencies Fluently

Most of the time, we need to arrange some behavior for our mocked dependencies:

var accountService = Substitute.For<IAccountService>();
accountService.FindEmail("[email protected]").Returns(new Account("foo"));

var mailService = Substitute.For<IMailService>();
mailService.SendMail("[email protected]").Returns(true);

var sut = new ResetPasswordController(
    accountService,
    Substitute.For<IAuditService>(),
    mailService);

With FluentArrange, you can use the Fluent API WithDependency<T> to achieve the exact same result as the code above:

var sut = Arrange.For<ResetPasswordController>()
    .WithDependency<IAccountService>(x => x.FindEmail("[email protected]").Returns(new Account("foo")))
    .WithDependency<IMailService>(x => x.SendMail("[email protected]").Returns(true));

As you might have noticed, we did not need to write arrange code for IAuditService, as that will be automatically created for you. The only time you need to call WithDependency<T> is when you need to arrange the behavior of type T.

Passing an instance instead

Sometimes, you may want to use a fake implementation rather than letting FluentArrange automatically create mocked instances.

In that case, you can provide an instance using WithDependency<T>(T):

var context = Arrange.For<ResetPasswordController>()
    .WithDependency<IAccountService>(new InMemoryAccountService());

or WithDependency<T>(T, Action<T>) if you need to do more arranging:

var context = Arrange.For<ResetPasswordController>()
    .WithDependency<IAccountService>(new InMemoryAccountService(), d =>
    {
        d.AddAccount("foo", "[email protected]");
        d.AddAccount("foobar", "[email protected]");
    });

or WithDependency<T, T2>(T2, Action<T2>) if you need to call T2-specific methods:

var context = Arrange.For<ResetPasswordController>()
    .WithDependency<IAccountService, InMemoryAccountService>(new InMemoryAccountService(), d =>
    {
        d.AddTestAccounts();
    });

Asserting Dependencies

Suppose you need to assert that a dependency's method has been called. Well, you simply arrange code with Arrange.For<T> instead of Arrange.Sut<T> to get a FluentArrangeContext object:

var context = Arrange.For<ResetPasswordController>();

To get the SUT, call the Sut property of the context:

var sut = context.Sut;

To get the Dependency, simply call Dependency<T>:

context.Dependency<IAccountService>();

or Dependency<T, T2> to get access to T2 and its specific methods:

context.Dependency<IAccountService, AccountService>();

When used together, a unit test could look like this:

// Arrange
var context = Arrange.For<ResetPasswordController>();

// Act
context.Sut.Reset("[email protected]");

// Assert
context.Dependency<IAccountService>().Received(1).FindEmail("[email protected]");

fluentarrange's People

Contributors

hhoangnl avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.