简单来说:
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 属性。
有人可以引导我走向正确的方向吗?似乎缺少了一些我无法理解的东西。
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.6 中 NUnit 的可扩展性 API 中的一些糟糕的设计选择(无法覆盖或删除任何内置测试用例提供程序),我被迫诉诸一些反射来获取内部 ExtensionCollection 实例“TestCaseProviders”类。
TL;DR:这应该仅适用于 NUnit 2.6.x。 NUnit 3.0 不兼容。
只需在已使用常规 [TestCase] 和 [TestCaseSource] 属性的测试上添加提供的 [AutoMoqData]。测试用例参数将首先被填充,其余的测试方法参数将通过 AutoFixture 处理。您可以根据需要更改 AutoMoqDataAttribute 以使用任何不同的夹具自定义(例如:AutoRhinoMockCustomization)。
如果将其添加到外部程序集并在测试项目中引用它,NUnit 将看不到您的加载项(因为它只在正在加载的直接测试程序集或当前项目的“addins”子文件夹中的 DLL 中查找)运行测试运行程序可执行文件。
在这种情况下,只需在当前测试项目中创建一个空类并使其继承自 AutoMoqDataAddIn。使用 ReSharper 单元测试运行程序进行测试,它可以正确查看测试用例,并仅使用“真实”测试参数自动生成测试用例名称。
GitHub:https://gist.github.com/rwasef1830/ab6353b43bfb6549b396
您可以使用范围、随机和值等
[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
}
了解更多信息: