Как передать динамические объекты в функцию NUnit TestCase? - PullRequest
48 голосов
/ 19 ноября 2010

Я пишу приложение с интенсивным использованием данных. У меня есть следующие тесты. Они работают, но они довольно избыточны.

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

Но это не работает, и я не уверен, как заставить это работать, или если это возможно.

Ответы [ 4 ]

112 голосов
/ 20 ноября 2010

Я отследил это.Я не могу передать экземпляр объекта в тест через TestCase, потому что атрибуты строго для статических метаданных.Но у команды NUnit есть решение для этого, TestCaseSource.Пост в списке NUnit, который ответил на вопрос: здесь .

Вот как выглядит мое решение:

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

Не так красиво, как я надеялсяне так легко читать.Но все же удалось сократить дублирование кода, что должно облегчить обслуживание и исправление.

6 голосов
/ 11 февраля 2014

Я передаю строки, которые иногда анализирую, думаю, что они читаются довольно хорошо, пример:

[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());
}
0 голосов
/ 19 марта 2019
 [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));
            };

    }
0 голосов
/ 19 ноября 2010

Не намного ли проще иметь закрытый метод, метод базового класса или вспомогательные классы, которые делают это для вас?

Для моих модульных тестов мне нужно много много фиктивных сущностей, потому что это оченьинтенсивное использование данных.Я создал структуру фиктивных репозиториев, которые могут создавать инициализированные сущности на лету, которые я могу комбинировать для создания репрезентативной структуры базы данных в памяти.

Что-то подобное может работать для вас:

// 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...