0

我有一个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);
        }
    }
}

到目前为止,我是否正确地接近这个?我知道这MapRegionFactoryIMapRegionGenerator通过 Castle.Windsor 进行注入,但是我如何模拟像生成器这样复杂的东西呢?我无法复制整个生成代码,不是吗?

4

2 回答 2

2

Why not use constructor injection, i.e. pass an instance of IMapRegionGenerator type to the constructor of MapRegionFactory class?

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

    ...
}

After this you can create mock for the IMapRegionGenerator type and pass it for testing.

于 2013-01-25T19:22:57.790 回答
1

I don't know enough about your code to know exactly how this test should look, but it ought to give you a basic idea of how to test the factory with a mock generator.

[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));
}

how do I mock something as complex as a generator? I can't replicate the whole generating code, no?

For the purpose of testing the factory, you just have to ensure that it uses the generator correctly, whatever correctly means. Your tests, like your production code for the factory, don't and should not care how a generator works, just that it fulfills its contract and returns a Region.

于 2013-01-26T15:36:46.207 回答