【问题标题】:InlineAutoDataAttribute but for NUnit (for TestCase and TestCaseSource)InlineAutoDataAttribute 但适用于 NUnit(适用于 TestCase 和 TestCaseSource)
【发布时间】:2014-07-17 07:45:40
【问题描述】:

简明扼要:

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 属性。

有人可以引导我走向正确的方向吗?好像缺少了什么我无法掌握的东西。

【问题讨论】:

  • AutoFixture.xUnit.net 和 AutoFixture.NUnit2 具有相似的类型名称,但它们建立在不同的对象模型上。 – 看起来你需要一个类似于InlineAutoDataAttributeTestCaseAutoDataAttribute
  • 这正是我想要的,但找不到。

标签: c# unit-testing testing nunit autofixture


【解决方案1】:

OP 的代码 here 在 nunit2.6.3 中对我不起作用。实际上它甚至没有编译,不确定 nunit 基础结构是否发生了变化。 原来我错过了nunit.core.dll 参考,添加后它编译了。但我使用了自己的实现。

所以我推出了自己的实现。实现是这样的:我们会向 AutoFixture 询问参数,它会给出 Test 方法需要的所有参数,然后我们将重写我们需要的参数值。

[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 的创建者),但他似乎也无能为力。所以现在我可以忍受这个了。

【讨论】:

  • FTR,不是我不想想要帮忙,而是我不能轻易做到。整个 NUnit 集成作为拉取请求提交给 AutoFixture,由于我自 2005 年以来就没有使用过 NUnit(ish),我对整个生态系统的运作方式知之甚少。
  • @MarkSeemann 不要误会我的意思。我没有说你不想帮忙。我的意思是你也帮不上忙。如果听起来不对,请见谅。我已经编辑过了。并感谢您的评论。我已经使它与一些天真的方法一起工作。这对我来说很好:)
  • 不用担心 - 我主要是想把评论留给将来可能会看到这一点但没有上下文的人:)
【解决方案2】:

我已经搞定了。

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

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

如何使用

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

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

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

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

给我看代码!

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

【讨论】:

  • 哎呀!这破坏了 TestCase 和 TestCaseSource 属性,将尽快修复它。
  • 已修复,忘记正确检查插件中的属性类型。
  • 它是 Autofixture 和 NUnit 的有用功能。你能向 AutoFixture.NUnit2 包发出拉取请求吗?
  • @sgnsajgon 有一些问题阻止了这值得拉请求......反射的丑陋使用和一些单元测试运行器(Resharper)的奇怪副作用不断显示测试多个每次运行时都会“忽略”。我现在没有时间诚实地做这件事。如果有人想接受它,请随意。
  • 这适用于 nunit 2.6.3 吗?你的要点在 nunit 2.6.3 中没有为我编译。 ExtensionsCollectionTestCaseParameterProvider 等不存在 :( 我是否遗漏了什么?autofixture 现在是否支持任何形式?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 2012-01-27
  • 2012-02-14
  • 2013-02-19
  • 2013-07-09
相关资源
最近更新 更多