要成为succint:
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对象[]以便测试方法中的第一个参数被填充时它不处理这种情况使用属性参数,其余的传递给AutoData属性。
有人可以引导我走向正确的方向吗?似乎有一些我无法掌握的东西。
答案 0 :(得分:3)
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的创建者),但似乎他也无法帮助解决这个问题。所以现在我可以忍受这个。
答案 1 :(得分:2)
我已经开始工作了。
不幸的是,由于NUnit的2.6中的可扩展性API中的一些糟糕的设计选择(无法覆盖或删除任何内置的测试用例提供程序),我被迫采取一些反思来获取“TestCaseProviders”类中的内部ExtensionCollection实例。
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