Creating Custom NUnit Assertions
page 4 of 5
by Brian Mains
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 34018/ 89

Data Table Asserts

The following is a constraint that checks for nulls in a DataTable, whether a column is not null or must only be null. The constraint has two constructors, one for the column name or index, and one for whether to check for nulls or not nulls, as shown below.

Listing 4

public class DataTableNullConstraint: NUnit.Framework.Constraints.Constraint
{
  private int _columnIndex =  - 1;
  private string _columnName = null;
  private bool _notNull = true;
 
  public DataTableNullConstraint(string columnName, bool notNull)
  {
    _columnName = columnName;
    _notNull = notNull;
  }
 
  public DataTableNullConstraint(int columnIndex, bool notNull)
  {
    _columnIndex = columnIndex;
    _notNull = notNull;
  }
}

The constraint uses the WriteDescriptionTo method to write a message line about the actual problem (whether the table has a null or not null value), using the MessageWriter object to write the message.

Listing 5

public override void WriteDescriptionTo(MessageWriter writer)
{
  writer.WriteMessageLine("The data table contains a {0} value", 
  _notNull ? "null" : "not null");
}

The matching of the object, in the Matches method, parses the table (passed in through the parameter) and determines whether fields have or do not have null values for a column.

Listing 6

public override bool Matches(object actual)
{
  base.actual = actual;
  if (actual == null || !(actual is DataTable))
    throw new ArgumentException("Actual value is not a DataTable""actual");
 
  DataTable table = actual as DataTable;
 
  foreach (DataRow row in table.Rows)
  {
    bool isNull = !string.IsNullOrEmpty(_columnName) ? row.IsNull(_columnName):
      row.IsNull(_columnIndex);
    if ((_notNull && isNull) || (!_notNull && !isNull))
      return false;
  }
 
  return true;
}

The first statement of this method is recommended by the NUnit documentation, assigning the actual value to the base method. It also validates the actual value, and if not a data table, an exception is thrown.

For each row in the table, if the column or index value is null or not null (depending on what is being searched for), a false is returned indicating a problem. When a false is returned to the caller, through Assert.That(), a false value means that an AssertionException exception is raised.  How this constructor is exposed is through a static assert class. Below is the method that looks for nulls:

Listing 7

public static void ColumnIsNotNull(DataTable table, string columnName, 
 string message, params object[] parameters)
{
  ColumnIs(table, columnName, true, message, parameters);
}
public static void ColumnIsNotNull(DataTable table, int columnIndex, 
 string message, params object[] parameters)
{
  ColumnIs(table, columnIndex, true, message, parameters);
}

I left out the other four overloads for brevity, as they pass the information directly along. The private ColumnIs global methods use the Assert.That method, creating a constraint and passing along the message parameters.

Listing 8

private static void ColumnIs(DataTable table, string columnName, bool notNull, 
 string message, params object[] parameters)
{
  Assert.That(table, new DataTableNullConstraint(columnName, notNull),
  message, parameters);
}
 
private static void ColumnIs(DataTable table, int columnIndex, bool notNull, 
 string message, params object[] parameters)
{
  Assert.That(table, new DataTableNullConstraint(columnIndex, notNull), 
  message, parameters);
}

If Matches returns false, an AssertionException is thrown and a call to the WriteDescriptionTo method renders any error details. That was a simplistic illustration.  Let us now take a look at one that uses reflection. I also built a ReflectionAssert which has the ability to compare two object's properties to ensure they are the same.

Listing 9

public override bool Matches(object actual)
{
  base.actual = actual;
  if (actual == null)
    throw new ArgumentNullException("actual");
 
  if (!string.IsNullOrEmpty(_propertyName))
  {
    PropertyInfo prop = _expectedObject.GetType().GetProperty(_propertyName);
    if (prop == null)
      throw new ArgumentNullException("prop");
    return prop.GetValue(_expectedObject, null).Equals(prop.GetValue(actual,
      null));
  }
  else
  {
    PropertyInfo[]props = _expectedObject.GetType().GetProperties();
    if (props == null || props.Length == 0)
      throw new ArgumentNullException("props");
 
    foreach (PropertyInfo prop in props)
    {
      if (!prop.GetValue(_expectedObject, null).Equals(prop.GetValue(actual,
        null)))
        return false;
    }
 
    return true;
  }
}

This example can be used to parse a single property, or parse multiple property values, depending on what expected criteria is provided.  If parsing all properties and only one of the values does not match, then a false value is returned; otherwise, true is returned.


View Entire Article

User Comments

Title: NUnit Test Generator   
Name: Thinzar
Date: 2012-07-02 1:55:11 AM
Comment:
I want to write NUnit Test generator tool. Pls tell me what features would be useful to add.
Title: NUnit Test Generator   
Name: Greg Finzer
Date: 2007-09-28 12:21:06 PM
Comment:
Brian, Thanks for the great article. I recently created a tool to create NUnit Tests. What other features would be useful to add?

http://www.kellermansoftware.com/p-30-nunit-test-generator.aspx

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-12-01 7:12:11 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search