InlineAutoDataAttribute 但适用于 NUnit(适用于 TestCase 和 TestCaseSource)

问题描述 投票:0回答:3

简单来说:

class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(new Fixture().Customize(new AutoMoqCustomization()))
    {
    }
}

public interface IWeapon { bool LaunchAtEarth(double probabilityOfHitting); }

public class DeathStar
{
    readonly IWeapon _weapon;

    public DeathStar(IWeapon weapon) // guard clause omitted for brevity
    {
        this._weapon = weapon;
    }

    public bool FireFromOrbit(double probabilityOfHitting)
    {
        return this._weapon.LaunchAtEarth(probabilityOfHitting);
    }
}

// Make me pass, pretty please with a cherry on the top
[Test, AutoMoqData]
[TestCase(0.1), TestCase(0.5), TestCase(1)]
public void AutoMoqData_should_fill_rest_of_arguments_that_are_not_filled_by_TestCase(
    double probabilityOfHitting,
    [Frozen] Mock<IWeapon> weapon,
    DeathStar platform)
{
    Assert.That(weapon, Is.Not.Null);
    Assert.That(platform, Is.Not.Null);
} // Ignored with error: Wrong number of parameters specified.

// Make me pass, too!
[Test, AutoMoqData]
[TestCaseSource("GetTestCases")]
public void AutoMoqData_should_fill_rest_method_arguments_that_are_not_filled_by_TestCaseSource(
    double probabilityOfHitting,
    [Frozen] Mock<IWeapon> weapon,
    DeathStar platform)
{
    Assert.That(weapon, Is.Not.Null);
    Assert.That(platform, Is.Not.Null);
} // Ignored with error: Wrong number of parameters specified.

IEnumerable<TestCaseData> GetTestCases()
{
    yield return new TestCaseData(0.1);
    yield return new TestCaseData(0.5);
    yield return new TestCaseData(1);
}

如果我使用 Xunit,这似乎可以解决问题: http://nikosbaxevanis.com/blog/2011/08/25/combining-data-theories-in-autofixture-dot-xunit-extension/ 我找不到 NUnit 的任何等效项。

这个:http://gertjvr.wordpress.com/2013/08/29/my-first-open-source-contribution/ 似乎已经在当前版本的 AutoFixture.NUnit2 (AutoData 属性)中工作,但是当我想让它采用 params object[] 以便填充测试方法中的第一个参数时,它无法处理这种情况使用属性参数,其余部分传递给 AutoData 属性。

有人可以引导我走向正确的方向吗?似乎缺少了一些我无法理解的东西。

c# unit-testing testing nunit autofixture
3个回答
3
投票

OP 的代码here在nunit2.6.3 中对我不起作用。事实上它甚至没有编译,不确定nunit基础设施是否已经改变。事实证明我错过了

nunit.core.dll
参考,添加它后,它编译了。但我使用了自己的实现。

所以我推出了自己的实现。实现是这样的:我们会向 AutoFixture 询问参数,它会给出测试方法需要的所有参数,然后我们只需覆盖我们需要的参数值即可。

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class InlineAutoDataAttribute : AutoDataAttribute
{
    private readonly object[] values;
    public InlineAutoDataAttribute(params object[] values)
        : base(new Fixture().Customize(new AutoMoqCustomization()))
    {
        this.values = values;
    }

    public override IEnumerable<object[]> GetData(MethodInfo method)
    {
        var testCaseData = base.GetData(method);

        foreach (object[] caseValues in testCaseData)
        {
            if (values.Length > caseValues.Length)
            {
                throw new InvalidOperationException("Number of parameters provided is more than expected parameter count");
            }
            Array.Copy(values, caseValues, values.Length);

            yield return caseValues;
        }
    }
}

使用方法:

[Test]
[InlineAutoData(1, 2)]
[InlineAutoData(3, 4)]
public void Whatever_Test_Name(int param1, int param2, TemplateOrder sut)
{
    //Your test here
    Assert.That(sut, Is.Not.Null);
}

测试将通过

调用
param1 = 1, param2 = 2, sut = given by auto fixture
param1 = 3, param2 = 4, sut = given by auto fixture

您可能会说这种实现效率不高,但至少可以按预期工作。我也联系了Mark Seemann(AutoFixture的创建者),但似乎他也无法帮助解决这个问题。所以现在我可以忍受这个。


2
投票

我已经成功了。

不幸的是,由于 2.6 中 NUnit 的可扩展性 API 中的一些糟糕的设计选择(无法覆盖或删除任何内置测试用例提供程序),我被迫诉诸一些反射来获取内部 ExtensionCollection 实例“TestCaseProviders”类

TL;DR:这应该仅适用于 NUnit 2.6.x。 NUnit 3.0 不兼容。

如何使用

只需在已使用常规 [TestCase] 和 [TestCaseSource] 属性的测试上添加提供的 [AutoMoqData]。测试用例参数将首先被填充,其余的测试方法参数将通过 AutoFixture 处理。您可以根据需要更改 AutoMoqDataAttribute 以使用任何不同的夹具自定义(例如:AutoRhinoMockCustomization)。

如何让它与 ReSharper 的测试运行器一起工作

如果将其添加到外部程序集并在测试项目中引用它,NUnit 将看不到您的加载项(因为它只在正在加载的直接测试程序集或当前项目的“addins”子文件夹中的 DLL 中查找)运行测试运行程序可执行文件。

在这种情况下,只需在当前测试项目中创建一个空类并使其继承自 AutoMoqDataAddIn。使用 ReSharper 单元测试运行程序进行测试,它可以正确查看测试用例,并仅使用“真实”测试参数自动生成测试用例名称。

显示代码!

GitHub:https://gist.github.com/rwasef1830/ab6353b43bfb6549b396


0
投票

您可以使用范围、随机和值等

[Test]
public void MyTest(
   [Values(1, 2, 3)] int x,
   [Random(-1.0, 1.0, 5)] double doubleRandom,
   [Range(0.2, 0.6, 0.2)] double doubleRange)
{
   //your tests
}

了解更多信息:

© www.soinside.com 2019 - 2024. All rights reserved.