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.

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.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
1.1.1 110 3/7/2020
1.1.0 7,841 11/21/2017
1.0.0 7,472 7/23/2016