RSpec-Let 1.1.1

When testing in C# it's not unusual to test instances of a class. The problem we
     all face is having a place to initialize our objects.

     1. Create a field that is initialized and reset on `[TearDown]`?
     2. Create a null field that is initialized during `[SetUp]`?
     3. Duplicate the initialization in every `[Test]`?

     All three of these are valid, and unfortunately, all three can be found in the
     same project and sometimes the same test!

Install-Package RSpec-Let -Version 1.1.1
dotnet add package RSpec-Let --version 1.1.1
<PackageReference Include="RSpec-Let" Version="1.1.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add RSpec-Let --version 1.1.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: RSpec-Let, 1.1.1"
For F# scripts that support #r syntax, copy this into the source code to reference the package.

Let.cs

When testing in C# it's not unusual to test instances of a class. The problem is
we all face though is knowing where to initialize our objects.

  1. Create a field that is initialized and reset on TearDown?
  2. Create a null field that is initialized during [SetUp]?
  3. Duplicate the initialization in every [Test]?

All three of these are valid, and unfortunately, all three can be found in the
same project and sometimes the same test!

namespace DoYourTestsLookLikeThis
{
    [TestFixture]
    public class InsertTearsEmoji
    {
        private UnitOfWork _work = new UnitOfWork();
        private Mock<IArticlesService> MockArticlesService { get; set; }

        [SetUp]
        public void BeforeEach()
        {
            MockArticlesService = new Mock<IArticlesService>();
        }

        [TearDown]
        public void AfterEach()
        {
            // 😭😭😭
            _work = new UnitOfWork();
        }

        [Test]
        public void IndexShouldLoadPublishedArticles()
        {
            var controller = new ArticlesController(MockArticlesService.Object);

            controller.Index();
            MockArticlesService.Verify(service => service.Published(), Times.Once);
        }
    }
}

It's dangerous to go alone, take Let.cs with you ðŸĪš

namespace HappyDance
{
    // This allows us to call +Let+ directly
    using static LetTestHelper.LetHelper;

    [TestFixture]
    public class ArticlesControllerTest
    {
        private UnitOfWork Work => Let(() => new UnitOfWork());
        private Mock<IArticlesService> MockArticlesService => Let(() => new Mock<IArticlesService>());

        // It's so easy, why not move it here too
        private ArticlesController Controller => Let(() => new ArticlesController(MockArticlesService.Object);

        [TearDown]
        public void AfterEach()
        {
            // You may cry, but only once (see below 👇)
            LetTestHelper.LetHelper.Flush();
        }

        [Test]
        public void IndexShouldLoadPublishedArticles()
        {
            Controller.Index();
            MockArticlesService.Verify(service => service.Published(), Times.Once);
        }
    }
}

Flush the Cache ðŸš―

  • After each test you will need to manually flush the results. My recommendation
    is creating a test helper that will flush the cache on tear down.
namespace MyProject.TestHelper
{
    [TestFixture]
    public class TestBase
    {
        [TearDown]
        public void Clean_LetHelper()
        {
            LetTestHelper.LetHelper.Flush();
        }
    }
}

Inspiration

Coming from Ruby I found instance management in C# to be, well, not fun. This is
is influenced by RSpec let.

Let.cs

When testing in C# it's not unusual to test instances of a class. The problem is
we all face though is knowing where to initialize our objects.

  1. Create a field that is initialized and reset on TearDown?
  2. Create a null field that is initialized during [SetUp]?
  3. Duplicate the initialization in every [Test]?

All three of these are valid, and unfortunately, all three can be found in the
same project and sometimes the same test!

namespace DoYourTestsLookLikeThis
{
    [TestFixture]
    public class InsertTearsEmoji
    {
        private UnitOfWork _work = new UnitOfWork();
        private Mock<IArticlesService> MockArticlesService { get; set; }

        [SetUp]
        public void BeforeEach()
        {
            MockArticlesService = new Mock<IArticlesService>();
        }

        [TearDown]
        public void AfterEach()
        {
            // 😭😭😭
            _work = new UnitOfWork();
        }

        [Test]
        public void IndexShouldLoadPublishedArticles()
        {
            var controller = new ArticlesController(MockArticlesService.Object);

            controller.Index();
            MockArticlesService.Verify(service => service.Published(), Times.Once);
        }
    }
}

It's dangerous to go alone, take Let.cs with you ðŸĪš

namespace HappyDance
{
    // This allows us to call +Let+ directly
    using static LetTestHelper.LetHelper;

    [TestFixture]
    public class ArticlesControllerTest
    {
        private UnitOfWork Work => Let(() => new UnitOfWork());
        private Mock<IArticlesService> MockArticlesService => Let(() => new Mock<IArticlesService>());

        // It's so easy, why not move it here too
        private ArticlesController Controller => Let(() => new ArticlesController(MockArticlesService.Object);

        [TearDown]
        public void AfterEach()
        {
            // You may cry, but only once (see below 👇)
            LetTestHelper.LetHelper.Flush();
        }

        [Test]
        public void IndexShouldLoadPublishedArticles()
        {
            Controller.Index();
            MockArticlesService.Verify(service => service.Published(), Times.Once);
        }
    }
}

Flush the Cache ðŸš―

  • After each test you will need to manually flush the results. My recommendation
    is creating a test helper that will flush the cache on tear down.
namespace MyProject.TestHelper
{
    [TestFixture]
    public class TestBase
    {
        [TearDown]
        public void Clean_LetHelper()
        {
            LetTestHelper.LetHelper.Flush();
        }
    }
}

Inspiration

Coming from Ruby I found instance management in C# to be, well, not fun. This is
is influenced by RSpec let.

  • .NETFramework 4.5

    • No dependencies.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
1.1.1 307 3/7/2020
1.1.0 17,352 11/21/2017
1.0.0 16,607 7/23/2016