c# - 如何使用 Autofixture 中的 RandomRangedNumberCustomization 来确保参数在一定范围内?

标签 c# unit-testing autofixture

我有一个带有两个参数的类,如下所示:

    public double X { get; private set; }

    public double Y { get; private set; }

    public Point(double x, double y)
    {
        if (x > 90 || x < -90)
            throw new ArgumentOutOfRangeException("latitude");

        if (y > 180 || y < -180)
            throw new ArgumentOutOfRangeException("longitude");

        X = x;
        Y = y;
    }

在构造函数中设置了相应的属性,所以我需要告诉AutoFixture创建一个Point类,其参数在guard子句中指定的范围内。我设法对 RandomRangedNumberCustomization 类的用法感到有点困惑。我做了以下事情:

        var xRange = new RangedNumberRequest(typeof(double), -90.0, 90.0);
        var yRange = new RangedNumberRequest(typeof (double), -180.0, 180.0);
        var dummyContext = new DelegatingSpecimenContext();
        var generator = new RandomRangedNumberGenerator();
        var x = (double)generator.Create(latitudeRange, dummyContext);
        var y = (double) generator.Create(longitudeRange, dummyContext);

这将在我的范围内生成数字,因此我可以创建一个点并输入这些生成的数字,但我在自定义方面遗漏了一些东西。非常感谢任何帮助和/或指导。

谢谢!

最佳答案

除了 Nikos Baxevanis 建议的解决方案外,还有另一种选择。您可以实现一个始终以特定方式处理 Pointxy 参数的约定:

public class PointCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Add(new XBuilder());
        fixture.Customizations.Add(new YBuilder());
    }

    private class XBuilder : ISpecimenBuilder
    {
        public object Create(object request, ISpecimenContext context)
        {
            var pi = request as ParameterInfo;
            if (pi == null ||
                pi.Name != "x" ||
                pi.Member.DeclaringType != typeof(Point))
                return new NoSpecimen(request);

            return context.Resolve(
                new RangedNumberRequest(typeof(double), -90d, 90d));
        }
    }

    private class YBuilder : ISpecimenBuilder
    {
        public object Create(object request, ISpecimenContext context)
        {
            var pi = request as ParameterInfo;
            if (pi == null ||
                pi.Name != "y" ||
                pi.Member.DeclaringType != typeof(Point))
                return new NoSpecimen(request);

            return context.Resolve(
                new RangedNumberRequest(typeof(double), -180d, 180d));
        }
    }
}

(以上代码还有重构的空间)

给定 PointCustomization,此测试通过:

[Fact]
public void CreatePointDoesNotThrow()
{
    var fixture = new Fixture().Customize(new PointCustomization());
    var e = Record.Exception(() => fixture.Create<Point>());
    Assert.Null(e);
}

关于c# - 如何使用 Autofixture 中的 RandomRangedNumberCustomization 来确保参数在一定范围内?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30351469/

相关文章:

c# - 如何使用 Visual c# Express 制作服务应用程序?

c# - 为 RSS 加载 XDocument 时出现 MonoDroid ObjectDisposedException

Android Studio 代码覆盖率未显示任何 Kotlin 类

Django 模型缓存?如何在测试中禁用

c# - 异常没有冒泡

c# - 通过声卡发出蜂鸣声

unit-testing - 使用哪个 Scala 框架来测试 REST 服务?

c# - 使用 AutoFixture 生成测试数据 : resolving ICollection<T> without mentioning every single T

moq - 什么是 AutoFixture AutoMoq?

c# - Task<IEnumerable<>> 自定义的 AutoFixture 自动设置返回类型