How can I pass dynamic objects into an NUnit TestCase function?

后端 未结 4 673
忘了有多久
忘了有多久 2020-12-12 22:10

I am writing a data-intensive application. I have the following tests. They work, but they\'re pretty redundant.

[Test]
public void DoSanityCheck_WithCountEqu         


        
相关标签:
4条回答
  • 2020-12-12 22:11

    It would be much much easier to have a private method, base class method, or helper classes that do this for you.

    For my unit tests, I need many many mock entities because it's a very data-intensive application. I've created a structure of mock repositories that can create initialized entities on the fly, which I can combine to build up a representative database structure in memory.

    Something like that could work for you:

    // 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 讨论(0)
  • 2020-12-12 22:12

    I pass strings that I parse sometimes, and I think it reads pretty well.

    Example:

    [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 讨论(0)
  • 2020-12-12 22:30
     [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 讨论(0)
  • 2020-12-12 22:32

    I tracked it down. I can't pass an instantiated object into a test via TestCase because attributes are strictly for static meta-data. But the NUnit team has a solution for that, TestCaseSource. The post on the NUnit list that answered the question is here.

    Here is what my solution now looks like:

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

    It is not as pretty as I hoped and is not as easy to read. But it did succeed on cutting down code duplication, which should make things easier to maintain and fix.

    0 讨论(0)
提交回复
热议问题