简体   繁体   English

用发电机对工厂进行单元测试

[英]Unit Testing a Factory with a Generator

I have a Factory class that uses a Generator class (there will be several of these, each with a different algorithm) to produce arrays of objects. 我有一个Factory类,它使用Generator类(其中有几种,每种都有不同的算法)来生成对象数组。 I am trying to program this with a TDD approach, but I'm having great difficulty with deciding on tests. 我正在尝试使用TDD方法对此进行编程,但是在决定测试时遇到了很大的困难。 I've barely just started with TDD, so I guess that my tests are, in fact, ugly abominations. 我才刚刚开始使用TDD,所以我想我的测试实际上是丑陋的可恶。

These are the tests I have on the Factory : 这些是我在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?
    }
}

And a single test for the Generator : 然后对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);
        }
    }
}

Am I approaching this correctly so far? 到目前为止,我是否正确解决了这个问题? I know that MapRegionFactory will have an IMapRegionGenerator injected through Castle.Windsor, but how do I mock something as complex as a generator? 我知道MapRegionFactory将通过IMapRegionGenerator注入一个IMapRegionGenerator ,但是我该如何模拟像生成器这样复杂的东西? I can't replicate the whole generating code, no? 我无法复制整个生成的代码,不是吗?

Why not use constructor injection , ie pass an instance of IMapRegionGenerator type to the constructor of MapRegionFactory class? 为什么不使用构造函数注入IMapRegionGenerator类型的实例传递给MapRegionFactory类的构造函数?

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

    ...
}

After this you can create mock for the IMapRegionGenerator type and pass it for testing. 之后,您可以为IMapRegionGenerator类型创建模拟并将其传递进行测试。

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. 您的测试(例如工厂的生产代码)不需要也不应该在乎生成器的工作原理,只是它已经履行了合同并返回了Region。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM