One of the interesting aspects of backfilling documentation is uncovering methods few seem to have discovered. Case in point, the Assert.AreValueEqual method in MbUnit v2. Rather than the straightforward AreEqual methods to compare the values of a property in an object or the AreSame methods to compare whether two objects are actually the identical object or of the same type, AreValueEqual verifies that two objects, expected and actual,

  • both have a property described a PropertyInfo object,
  • that the property is not null,
  • and that the value of the property in both objects is equal.

It's a bit of a black box tester then and works across class hierarchies.

[more]

AreValueEqual takes three parameters and an optional fourth.

  • The PropertyInfo object indicating the property to be tested
  • The object containing the expected value of the property
  • The object containing the actual value of the property
  • The index of the value to compare in the property if it is an indexed property

Let's take a few examples to demonstrate its various pass and fail scenarios. First, some boilerplate. You'll need to include System.Reflection for the PropertyInfo class and MbUnit.Framework for the Assert class.

using System;
using System.Reflection;
using MbUnit.Framework;

namespace MbUnitAssertDocs
{
[TestFixture]
public class AreValueEqualTests
{

The first test passes as it compares the Length property of two string arrays both containing four strings. Only the Length property is being tested here, so whether the strings are equal is irrelevant

      //This test passes
      [Test]
      public void AreValueEqual_SameValues()
      {
         // Create two arrays
         String[] a = new String[4] { "this", "is", "a", "test" };
         String[] b = new String[4] { "this", "is", "a", "camel" };
      
         // Generate the PropertyInfo object for an array's length
         PropertyInfo pi = typeof(Array).GetProperty("Length");
         Assert.AreValueEqual(pi, a, b);
      }

The next test also passes and demonstrates using the optional fourth parameter to test the value of an indexed property. In this case, we're treating a String object as an array of Char and testing the fourth character.

      //This test passes
      [Test]
      public void AreValueEqual_SameValuesUsingIndices()
      {
         // Create two strings
         String a = "this is a test";
         String b = "this is a camel";

         // Generate the PropertyInfo object for the string as a Char array 
         PropertyInfo pi = typeof(String).GetProperty("Chars");

         // Test the fourth letter
         Assert.AreValueEqual(pi, a, b, new Object[] {4});
      }

If one of the objects being tested is null, the test fails with an AssertionException.

      // This test fails with an AssertionException
      [Test]
      public void AreValueEqual_OneValueIsNull()
      {
         // Create two arrays
         String[] a = new String[4] { "this", "is", "a", "test" };
      
         // Generate the PropertyInfo object for an array's length
         PropertyInfo pi = typeof(Array).GetProperty("Length");
      
         Assert.AreValueEqual(pi, a, null);
      }

If one of the objects does not have the property specified by the PropertyInfo object, the test also fails with an AssertionException. This next test fails because the String reference class has a Chars property while the string value type does not. (One capitalised letter makes all the difference)

      //This test fails with an AssertionException
      [Test]
      public void AreValueEqual_PropertyNotPresentInOneObject()
      {
         // Create two arrays
         String[] a = new String[4] { "this", "is", "a", "test" };
         string[] b = new string[4] { "this", "is", "a", "camel" };
      
         // Generate the PropertyInfo object for an array's length
         PropertyInfo pi = typeof(Array).GetProperty("Chars");
      
         Assert.AreValueEqual(pi, a, b, new Object[] {4});
      }

Finally, if the value of the property shared by the two objects does not have the same value, the test fails with a NotEqualAssertionException.

      //This test fails with a NotEqualAssertionException
      [Test]
      public void AreValueEqual_DifferentValues()
      {
         // Create two strings
         String a = "this is a test";
         String b = "this is a camel";
      
         // Generate the PropertyInfo object for the string as a Char array 
         PropertyInfo pi = typeof(String).GetProperty("Chars");
      
         // Test the tenth letter
         Assert.AreValueEqual(pi, a, b, new Object[] { 10 });
      }
   }
}

Hopefully, this gives you a few ideas on how you might use Assert.AreValueEqual. MbUnit itself uses it in our DataAssert class, the source for which you can see here. There's also a discussion on the MbUnit-User forum discussing this method and whether or not it should make it into MbUnit v3. If you'd like to see it stay, or would like to propose an alternative, reply to the thread.