【问题标题】:Unit Testing a Factory with a Generator使用生成器对工厂进行单元测试
【发布时间】:2013-01-25 17:35:43
【问题描述】:

我有一个Factory 类,它使用Generator 类(其中会有几个,每个都有不同的算法)来生成对象数组。我正在尝试使用 TDD 方法对此进行编程,但在决定测试时遇到了很大困难。我才刚刚开始使用 TDD,所以我想我的测试实际上是丑陋的可憎之物。

这些是我在Factory 上的测试:

[TestFixture]
public class MapRegionFactoryTests
{
    [Test,
     Description("Tests if a MapRegion is successfully created.")]
    public void TestBasicRegionCreation()
    {
        var mapRegionFactory = new MapRegionFactory();
        MapRegion mapRegion = mapRegionFactory.GenerateMapRegion();

        Assert.IsTrue(mapRegion != null);
    }

    [Test,
     Description("Tests if a MapRegionFactory's RegionSizeX, RegionSizeY and RegionSizeZ are properly initialized" +
                 "to their default values.")]
    public void TestDefaultPropertyInitialization()
    {
        var mapRegionFactory = new MapRegionFactory();

        Assert.Greater(mapRegionFactory.RegionSizeX, 0);
        Assert.Greater(mapRegionFactory.RegionSizeY, 0);
        Assert.Greater(mapRegionFactory.RegionSizeZ, 0);
    }

    [Test,
     Description("Tests if properties can only be assigned numbers above zero.")]
    public void TestGreaterThanZeroPropetyAssignment()
    {
        var mapRegionFactory = new MapRegionFactory
                               {
                                   RegionSizeX = -8,
                                   RegionSizeY = -3,
                                   RegionSizeZ = 0
                               };

        Assert.Greater(mapRegionFactory.RegionSizeX, 0);
        Assert.Greater(mapRegionFactory.RegionSizeY, 0);
        Assert.Greater(mapRegionFactory.RegionSizeZ, 0);
    }

    [Test,
    Description("Tests if the default RegionFactory can deliver a region filled with tiles.")]
    public void TestRegionCount()
    {
        // Test the count of objects again?
    }
}

Generator 进行一次测试:

[TestFixture]
public class MapRegionGeneratorTests
{
    [Test,
     Description("Tests that a region of a certain size is properly filled with Block objects.")]
    public void TestDefaultRegionSize()
    {
        const int regionSize = 16;

        var mapRegionGenerator = new MapRegionGenerator();

        var regionData = mapRegionGenerator.GenerateRegion(regionSize);

        foreach (Block element in regionData)
        {
            Assert.IsNotNull(element);
        }
    }
}

到目前为止,我的处理方法正确吗?我知道MapRegionFactory 将通过Castle.Windsor 注入IMapRegionGenerator,但是我如何模拟像生成器这样复杂的东西呢?我无法复制整个生成代码,不是吗?

【问题讨论】:

    标签: c# unit-testing tdd nunit


    【解决方案1】:

    为什么不使用构造函数注入,即将IMapRegionGenerator类型的实例传递给MapRegionFactory类的构造函数?

    class MapRegionFactory
    {
        public MapRegionFactory(IMapRegionGenerator generator)
        {
            ...
        }
    
        ...
    }
    

    在此之后,您可以为 IMapRegionGenerator 类型创建模拟并通过它进行测试。

    【讨论】:

    • 这正是我要做的——这没有任何问题。我确实有一个问题是如何实际模拟和单元测试生成器。我只是复制粘贴生成代码吗?还是我返回一些随机对象数组?
    • @PavelMatuska,您能否在问题中添加IMapRegionGenerator 接口的定义?
    • 另一个答案是正确的,但感谢您的努力。我对这两个答案都加了一个。
    【解决方案2】:

    我对您的代码了解不多,无法确切知道该测试的外观,但它应该可以让您大致了解如何使用模拟生成器测试工厂。

    [Test]
    public void RegionFactoryDelegatesToRegionGenerator()
    {
        var mockGenerator = new Mock<IMapRegiongenerator>();
        var factory = new MapRegionFactory(mockGenerator.Object);
    
        var expectedRegion = new Region();
        var regionSize = CreateRandomRegionSize();
        mockGenerator.Setup(g=>g.GenerateRegion(regionSize)).Returns(expectedRegion);
    
        factory.SetRegionSize(regionSize);
        Assert.That(factory.GetRegion(), Is.SameAs(expectedRegion));
    }
    

    如何模拟像生成器这样复杂的东西?我无法复制 整个生成代码,不是吗?

    为了测试工厂,您只需要确保它正确使用生成器,无论正确意味着什么。你的测试,就像你的工厂生产代码一样,不关心也不应该关心生成器是如何工作的,只关心它履行合同并返回一个区域。

    【讨论】:

    • 最后一句是我一直在寻找的。不知道是需要复制生成代码还是只是测试工厂如何使用生成器。
    猜你喜欢
    • 2011-06-23
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    • 2011-10-18
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多