HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Can these unit tests be improved?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
cantheseimprovedtestsunit

Problem

I'm not the greatest at writing tests yet and I'm starting a new OSS project for learning and as part of it I want to tackle being more effective at writing tests, more specifically quality tests. I think I write a lot of tests that don't bring much value except maintenance pain sometimes.

Can I improve these tests?

```
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using FakeItEasy;
using HaywireMQ.Server.Channel;
using HaywireMQ.Server.MessageStore;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoFakeItEasy;

namespace HaywireMQ.Server.Tests
{
///
/// Tests for HaywireServer
///
[TestClass]
public class HaywireServerTests
{
private IFixture fixture;

public HaywireServerTests()
{
}

[TestInitialize]
public void Initialize()
{
fixture = new Fixture().Customize(new AutoFakeItEasyCustomization());
}

[TestMethod]
public void Should_use_defaults_without_ModuleCatalog()
{
// Given
var target = new HaywireServer();

// When
target.Start();

// Then
Assert.AreEqual(target.MessageStore.GetType(), typeof(InMemoryMessageStore));
Assert.AreEqual(target.MessageChannel.GetType(), typeof(InMemoryMessageChannel));
}

[TestMethod]
public void Should_use_ModuleCatalog()
{
// Given
var catalog = new ModuleCatalog();
var messageStore = fixture.CreateAnonymous();
var messageChannel = fixture.CreateAnonymous();
catalog.MessageStores.Add(messageStore);
catalog.MessageChannels.Add(messageChannel);
var target = new HaywireServer(catalog);

// When
target.Start();

// Then
Assert.AreEqual(target.MessageStore.GetType(), messag

Solution

Assuming that I've correctly managed to extrapolate the SUT and friends from the question, I'd reduce the tests to the following. Please note that this focuses only on AutoFixture mechanics, and not on the general design of neither test nor SUT API.

AFAICT, the following tests state the same as the tests in the OP, but reduced to only the necessary statements. Still, I agree with Nikos Baxevanis that it would be possible to reduce these tests dramatically with xUnit.net instead of MSTest.

using System.Collections.Generic;
using System.Linq;
using FakeItEasy;
using FirstAutoFixtureReviewForKellySommers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoFakeItEasy;
using Ploeh.AutoFixture.Kernel;

namespace HaywireMQ.Server.Tests
{
    /// 
    /// Tests for HaywireServer
    /// 
    [TestClass]
    public class HaywireServerTests
    {
        [TestMethod]
        public void Should_use_defaults_without_ModuleCatalog()
        {
            // Given
            var fixture = new Fixture().Customize(new TestConventions());

            // When
            var target = fixture.CreateAnonymous();

            // Then
            Assert.IsInstanceOfType(target.MessageStore, typeof(InMemoryMessageStore));
            Assert.IsInstanceOfType(target.MessageChannel, typeof(InMemoryMessageChannel));
        }

        [TestMethod]
        public void Should_use_ModuleCatalog()
        {
            // Given
            var fixture = new Fixture().Customize(new TestConventions());

            var catalog = fixture.Freeze();
            fixture.AddManyTo(catalog.MessageStores, 1);
            fixture.AddManyTo(catalog.MessageChannels, 1);

            // When
            var target = fixture.CreateAnonymous();

            // Then
            Assert.AreEqual(catalog.MessageStores.Single(), target.MessageStore);
            Assert.AreEqual(catalog.MessageChannels.Single(), target.MessageChannel);
        }

        [TestMethod]
        public void Should_create_MessageQueue()
        {
            // Given
            var fixture = new Fixture().Customize(new TestConventions());

            var catalog = fixture.Freeze();
            fixture.AddManyTo(catalog.MessageStores, 1);

            List ids = fixture.CreateMany(1).ToList();
            A.CallTo(() => catalog.MessageStores.Single().GetQueues()).Returns(ids);

            var target = fixture.CreateAnonymous();

            // When
            target.Start();

            // Then
            A.CallTo(() => catalog.MessageStores.Single().GetQueues()).MustHaveHappened();
            Assert.AreEqual(1, target.MessageQueues.Count);
            Assert.AreEqual(ids.First(), target.MessageQueues[0].Id);
        }

        private class TestConventions : CompositeCustomization
        {
            public TestConventions()
                : base(
                    new AutoFakeItEasyCustomization(),
                    new GreedyHaywireServerCustomization())
            {
            }
        }

        private class GreedyHaywireServerCustomization : ICustomization
        {
            public void Customize(IFixture fixture)
            {
                fixture.Customize(c =>
                    c.FromFactory(new MethodInvoker(new GreedyConstructorQuery())));
            }
        }
    }
}

Code Snippets

using System.Collections.Generic;
using System.Linq;
using FakeItEasy;
using FirstAutoFixtureReviewForKellySommers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoFakeItEasy;
using Ploeh.AutoFixture.Kernel;

namespace HaywireMQ.Server.Tests
{
    /// <summary>
    /// Tests for HaywireServer
    /// </summary>
    [TestClass]
    public class HaywireServerTests
    {
        [TestMethod]
        public void Should_use_defaults_without_ModuleCatalog()
        {
            // Given
            var fixture = new Fixture().Customize(new TestConventions());

            // When
            var target = fixture.CreateAnonymous<HaywireServer>();

            // Then
            Assert.IsInstanceOfType(target.MessageStore, typeof(InMemoryMessageStore));
            Assert.IsInstanceOfType(target.MessageChannel, typeof(InMemoryMessageChannel));
        }

        [TestMethod]
        public void Should_use_ModuleCatalog()
        {
            // Given
            var fixture = new Fixture().Customize(new TestConventions());

            var catalog = fixture.Freeze<ModuleCatalog>();
            fixture.AddManyTo(catalog.MessageStores, 1);
            fixture.AddManyTo(catalog.MessageChannels, 1);

            // When
            var target = fixture.CreateAnonymous<HaywireServer>();

            // Then
            Assert.AreEqual(catalog.MessageStores.Single(), target.MessageStore);
            Assert.AreEqual(catalog.MessageChannels.Single(), target.MessageChannel);
        }

        [TestMethod]
        public void Should_create_MessageQueue()
        {
            // Given
            var fixture = new Fixture().Customize(new TestConventions());

            var catalog = fixture.Freeze<ModuleCatalog>();
            fixture.AddManyTo(catalog.MessageStores, 1);

            List<string> ids = fixture.CreateMany<string>(1).ToList();
            A.CallTo(() => catalog.MessageStores.Single().GetQueues()).Returns(ids);

            var target = fixture.CreateAnonymous<HaywireServer>();

            // When
            target.Start();

            // Then
            A.CallTo(() => catalog.MessageStores.Single().GetQueues()).MustHaveHappened();
            Assert.AreEqual(1, target.MessageQueues.Count);
            Assert.AreEqual(ids.First(), target.MessageQueues[0].Id);
        }

        private class TestConventions : CompositeCustomization
        {
            public TestConventions()
                : base(
                    new AutoFakeItEasyCustomization(),
                    new GreedyHaywireServerCustomization())
            {
            }
        }

        private class GreedyHaywireServerCustomization : ICustomization
        {
            public void Customize(IFixture fixture)
            {
                fixture.Customize<HaywireServer>(c =>
                    c.FromFactory(new MethodInvoker(new GreedyConstructorQuery())));
            }
        }
    }
}

Context

StackExchange Code Review Q#8528, answer score: 8

Revisions (0)

No revisions yet.