Jak przekazać obiekty dynamiczne do funkcji NUnit TestCase?

Piszę aplikację intensywnie wykorzystującą dane. Mam następujące testy. Działają, ale są zbędne.

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

Te same właściwości są modyfikowane na początku, podobnie jak dzieci różnych obiektów kontenera, a kilka wartości w twierdzeniu zmienia się na końcu. Muszę napisać kilkadziesiąt takich, sprawdzając różne właściwości. Chcę więc sparametryzować test. Sztuczka polega na przekazaniu obiektu kontenera jako parametru do testu. Obiekt kontenera jest inicjowany w ustawieniu urządzenia testowego.

To, co chcę osiągnąć, wyglądałoby mniej więcej tak:

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

Ale to nie działa i nie jestem pewien, jak to zrobić, czy to możliwe.

 42
Author: Alexander Garden, 2010-11-19

3 answers

Namierzyłem go. Nie mogę przekazać obiektu instancyjnego do testu przez TestCase, ponieważ atrybuty są wyłącznie dla statycznych metadanych. Ale zespół NUnit ma na to rozwiązanie, TestCaseSource. Post na liście NUnit, który odpowiedział na pytanie jest Tutaj .

Oto jak teraz wygląda moje rozwiązanie:

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);
}
Nie tak ładna, jak się spodziewałam, nie tak łatwa do odczytania. Udało się jednak ograniczyć powielanie kodu, co powinno ułatwić utrzymanie i napraw.
 97
Author: Alexander Garden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-19 23:34:45

Przekazuję struny, które czasami analizuję, myślę, że czyta się całkiem dobrze, przykład:

[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());
}
 5
Author: Johan Larsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-16 18:45:59

Czy nie byłoby o wiele łatwiej mieć metodę prywatną, metodę klasy bazowej lub klasy pomocnicze, które robią to za Ciebie?

Do moich testów jednostkowych potrzebuję wielu, wielu pozorowanych jednostek, ponieważ jest to bardzo intensywna aplikacja. Stworzyłem strukturę makiet repozytoriów, które mogą tworzyć inicjowane jednostki w locie, które mogę połączyć, aby zbudować reprezentatywną strukturę bazy danych w pamięci.

Coś takiego może Ci się udać:

// 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);
}
 0
Author: Pieter van Ginkel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-19 06:36:50