Home > Software engineering >  Assert object wasn't changed in UnitTest
Assert object wasn't changed in UnitTest

Time:03-10

I have an unit test, where I want to test, that under some circumstances my class hasn't been changed.

[Test]
public void ShouldNotRecalculate()
{
    var subject = new Invoice();
    //Create50InvoiceItems()
    sut.Recalculate(subject);
    Assert.That(subject.Items[0].NetAmount.Equals());
    Assert.That(subject.Items[0].VatRate.Equals());
    ...
    Assert.That(subject.Items[49].NetAmount.Equals());
    Assert.That(subject.Items[49].VatRate.Equals());
}

Without creating variables and saving there old values of those all 50 invoice items, is there any other solution? Should I create a shallow copy of this object? Maybe using AutoMapper?

Thank in advance!

CodePudding user response:

Maybe you can compare enumerables for each property, something like this:

public void ShouldNotRecalculate()
{
  var subject = new Invoice();
  //Create50InvoiceItems()
    
  var netAmounts = subject.Items.Select(i => i.NetAmount);
  var vatRates = subject.Items.Select(i => i.VatRate);
    
  sut.Recalculate(subject);
    
  Assert.IsTrue(netAmounts.SequenceEqual(subject.Items.Select(i => i.NetAmount)));
  Assert.IsTrue(vatRates.SequenceEqual(subject.Items.Select(i => i.VatRate)));
}

CodePudding user response:

I sometimes implemented the IEquatable interface so that I can compare objects and all it's properties. It's quite handy in general, and also allows you to create a "reference object" or an object and compare and check if it has been changed.

Depending on the situation you may also just create multiple assertions and check all values. For those cases I like to use Assert.Multiple() to signify that the values belong together.

In your case I would go for the IEquatable interface, this makes the Assertions super concise.

On top IClonable will make the preparation of the test data easy.

I wonder though - how many objects do you have to test to "proof" your code is working correctly? Sure, you may have to make a test for each property, but per property, I guess only a few tests should be necessary. Besides - you can use [TestCaseSource] and potentially [Combinatorical] attributes to generate the test cases necessary. Then you don't need to create a huge list with test case data yourself. Meaning - instead of creating a huge list of test case data yourself and test them all in a huge test, let NUnit generate the data for you and run it in many test cases.

  • Related