usuario procesando por objetos objeto fórmulas dinámicamente dinamicos dinamicamente crear creadas controles arreglos c# nunit

c# - procesando - ¿Cómo pasar objetos dinámicos a una función NUnit TestCase?



objetos dinamicos c# (3)

Estoy escribiendo una aplicación intensiva de datos. Tengo las siguientes pruebas. Funcionan, pero son bastante redundantes.

[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); }

Las mismas propiedades se modifican al principio, al igual que los hijos de diferentes objetos contenedores, y un par de valores en la afirmación cambian al final. Necesito escribir algunas docenas de estas, verificando diferentes propiedades. Así que quiero parametrizar la prueba. El truco es pasar el objeto contenedor como un parámetro a la prueba. El objeto contenedor se crea una instancia en el dispositivo de prueba SetUp.

Lo que quiero lograr sería algo así:

[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); }

Pero eso no funciona y no estoy seguro de cómo hacerlo funcionar, o si es posible.


¿No sería mucho más fácil tener un método privado, un método de clase base o clases auxiliares que hagan esto por usted?

Para mis pruebas de unidad, necesito muchas muchas entidades simuladas porque es una aplicación muy intensiva en datos. He creado una estructura de repositorios simulados que pueden crear entidades inicializadas sobre la marcha, que puedo combinar para construir una estructura de base de datos representativa en la memoria.

Algo así podría funcionar para ti:

// 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); }


Lo rastreé. No puedo pasar un objeto instanciado a una prueba a través de TestCase porque los atributos son estrictamente para metadatos estáticos. Pero el equipo NUnit tiene una solución para eso, TestCaseSource. La publicación en la lista NUnit que respondió la pregunta está here .

Aquí es como se ve mi solución ahora:

public IEnumerable<TestCaseData> CountEqualsZeroAndHouseGrossIsGreaterTestCases { get { Setup(); 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); }

No tan bonito como esperaba, no tan fácil de leer. Pero sí logró reducir la duplicación de código, lo que debería facilitar el mantenimiento y la solución.


Paso cadenas que analizo a veces, creo que se lee bastante bien, ejemplo:

[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()); }