[英]How to pass struct parameter to test function by using [TestCase] or [TestCaseSource] in NUNIT
[英]How can I pass dynamic objects into an NUnit TestCase function?
我正在编写一个数据密集型应用程序。 我有以下测试。 他们工作,但他们是相当多余的。
[Test]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InMerchantAggregateTotals_SetsWarning()
{
report.Merchants[5461324658456716].AggregateTotals.ItemCount = 0;
report.Merchants[5461324658456716].AggregateTotals._volume = 0;
report.Merchants[5461324658456716].AggregateTotals._houseGross = 1;
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == 5461324658456716 && x.lineitem == "AggregateTotals").Count() > 0);
}
[Test]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotals_SetsWarning()
{
report.AggregateTotals.ItemCount = 0;
report.AggregateTotals._volume = 0;
report.AggregateTotals._houseGross = 1;
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "AggregateTotals").Count() > 0);
}
[Test]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotalsLineItem_SetsWarning()
{
report.AggregateTotals.LineItem["WirelessPerItem"].ItemCount = 0;
report.AggregateTotals.LineItem["WirelessPerItem"]._volume = 0;
report.AggregateTotals.LineItem["WirelessPerItem"]._houseGross = 1;
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "WirelessPerItem").Count() > 0);
}
相同的属性在开始时被修改,就像不同容器对象的子代一样,并且断言中的几个值在最后发生变化。
我需要写几十个这样的,检查不同的属性。 所以我想参数化测试。 诀窍是将容器对象作为参数传递给测试。 容器对象在测试装置 SetUp 中实例化。
我想实现这样的目标:
[TestCase(report.AggregateTotals.LineItem["WirelessPerItem"], 0, "WirelessPerItem")]
[TestCase(report.AggregateTotals, 4268435971532164, "AggregateTotals")]
[TestCase(report.Merchants[5461324658456716].AggregateTotals, 5461324658456716, "WirelessPerItem")]
[TestCase(report.Merchants[4268435971532164].LineItem["EBTPerItem"], 4268435971532164, "EBTPerItem")]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_TestCase_SetsWarning(object container, long mid, string field)
{
container.ItemCount = 0;
container._volume = 0;
container._houseGross = 1;
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == mid && x.lineitem == field).Count() > 0);
}
但这不起作用,我不确定如何使它起作用,或者是否可能。
我追踪了它。 我无法通过 TestCase 将实例化对象传递到测试中,因为属性严格用于静态元数据。 但是 NUnit 团队有一个解决方案,TestCaseSource。 NUnit 列表上回答问题的帖子在这里。
这是我的解决方案现在的样子:
public static IEnumerable<TestCaseData> CountEqualsZeroAndHouseGrossIsGreaterTestCases
{
get
{
yield return new TestCaseData(report, report.Merchants[4268435971532164].LineItem["EBTPerItem"], 4268435971532164, "EBTPerItem").SetName("ReportMerchantsLineItem");
yield return new TestCaseData(report, report.Merchants[5461324658456716].AggregateTotals, 5461324658456716, "WirelessPerItem").SetName("ReportMerchantsAggregateTotals");
yield return new TestCaseData(report, report.AggregateTotals, null, "AggregateTotals").SetName("ReportAggregateTotals");
yield return new TestCaseData(report, report.AggregateTotals.LineItem["WirelessPerItem"], null, "WirelessPerItem").SetName("ReportAggregateTotalsLineItem");
}
}
[TestCaseSource("CountEqualsZeroAndHouseGrossIsGreaterTestCases")]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_TestCase_SetsWarning(Reports.ResidualsReport report, Reports.LineItemObject container, long? mid, string field)
{
container.ItemCount = 0;
container._volume = 0;
container._houseGross = 1;
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x=> x is Reports.WarningObjects.ImbalancedVariables && x.mid == mid && x.lineitem == field).Count() > 0);
}
它没有我希望的那么漂亮,也没有那么容易阅读。 但它确实成功地减少了代码重复,这应该会使事情更容易维护和修复。
我有时会传递我解析的字符串,我认为它读起来很好。
例子:
[TestCase("15°", "-10°", 25, typeof(Degrees))]
[TestCase("-10°", "15°", -25, typeof(Degrees))]
[TestCase("-10°", "0°", -10, typeof(Degrees))]
[TestCase("-90°", "1.5707 rad", -3.1414, typeof(Radians))]
[TestCase("1.5707 rad", "-90°", 3.1414, typeof(Radians))]
[TestCase("1.5707 rad", "1.5707 rad", 0, typeof(Radians))]
public void SubtractionTest(string lvs, string rvs, double ev, Type et)
{
var lv = Angle.Parse(lvs);
var rv = Angle.Parse(rvs);
var diff = lv - rv;
Assert.AreEqual(ev, diff.Value, 1e-3);
Assert.AreEqual(et, diff.Unit.GetType());
}
拥有为您执行此操作的私有方法、基类方法或辅助类会容易得多。
对于我的单元测试,我需要很多模拟实体,因为它是一个非常数据密集型的应用程序。 我创建了一个模拟存储库结构,可以动态创建初始化的实体,我可以将它们组合起来在内存中构建一个有代表性的数据库结构。
像这样的东西可能对你有用:
// Wild guess at the class name, but you get the idea
private void InitializeTotals(AggregateItem item)
{
item.ItemCount = 0;
item._volume = 0;
item._houseGross = 1;
}
[Test]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InMerchantAggregateTotals_SetsWarning()
{
InitializeTotals(report.Merchants[5461324658456716].AggregateTotals);
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x => x is Reports.WarningObjects.ImbalancedVariables && x.mid == 5461324658456716 && x.lineitem == "AggregateTotals").Count() > 0);
}
[Test]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotals_SetsWarning()
{
InitializeTotals(report.AggregateTotals);
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x => x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "AggregateTotals").Count() > 0);
}
[Test]
public void DoSanityCheck_WithCountEqualsZeroAndHouseGrossIsGreater_InAggregateTotalsLineItem_SetsWarning()
{
InitializeTotals(report.AggregateTotals.LineItem["WirelessPerItem"]);
report.DoSanityCheck();
Assert.IsTrue(report.FishyFlag);
Assert.That(report.DataWarnings.Where(x => x is Reports.WarningObjects.ImbalancedVariables && x.mid == null && x.lineitem == "WirelessPerItem").Count() > 0);
}
[Test]
[TestCase("textbox", true, "Text is empty", null, false)]
[TestCase("textbox", false, "Text is empty", null, true)]
public void Test_Component_Validation_and_ValidationText__Whether_IsMandatory_IsSet(string textbox, bool isMandatory, string validationText, string value, bool expectedValue)
{
// Arrange
var mockPublicPortalService = new Mock<IPublicPortalService>();
PublicAssessmentController controller = new PublicAssessmentController(mockPublicPortalService.Object);
// Set Component properties
var Component = new Component()
{
ComponentDatatype = textbox,
IsMandatory = isMandatory,
ValidationText = validationText,
Value = value
};
var context = new ValidationContext(Component);
// Act
var results = new List<ValidationResult>();
var isModelStateValid = Validator.TryValidateObject(Component, context, results, true);
// Assert
Assert.AreEqual(expectedValue, isModelStateValid);
if (isModelStateValid == false)
{
Assert.IsTrue(results.Any(x => x.ErrorMessage == validationText));
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.