20.2. Asserting the Facts

So far, this chapter has examined the structure of the test environment and how test cases are nested within test classes in a test project. What remains is to look at the body of the test case and review how test cases either pass or fail. (When a test case is generated, you saw that an Assert.Inconclusive statement is added to the end of the test to indicate that it is incomplete.)

The idea behind unit testing is that you start with the system, component, or object in a known state, and then run a method, modify a property, or trigger an event. The testing phase comes at the end, when you need to validate that the system, component, or object is in the correct state. Alternatively, you may need to validate that the correct output was returned from a method or property. You do this by attempting to assert a particular condition. If this condition is not true, the testing system reports this result and ends the test case. A condition is asserted, not surprisingly, via the Assert class. There is also a StringAssert class and a CollectionAssert class, which provide additional assertions for dealing with String objects and collections of objects, respectively.

20.2.1. Assert

The Assert class in the UnitTesting namespace, not to be confused with the Debug.Assert or Trace.Assert method in the System.Diagnostics namespace, is the primary class used to make assertions about a test case. The basic assertion has the following format:

Assert.IsTrue(variableToTest, "Output message if this fails")

As you can imagine, the first argument is the condition to be tested. If this is true, the test case continues operation. However, if it fails, the output message is emitted and the test case exits with a failed result.

There are multiple overloads to this statement whereby the output message can be omitted or String formatting parameters supplied. Because quite often you won't be testing a single positive condition, several additional methods simplify making assertions within a test case:

  • IsFalse: Tests for a negative, or false, condition

  • AreEqual: Tests whether two arguments have the same value

  • AreSame: Tests whether two arguments refer to the same object

  • IsInstanceOfType: Tests whether an argument is an instance of a particular type

  • IsNull: Tests whether an argument is nothing

This list is not exhaustive — there are several more methods, including negative equivalents of those listed. Also, many of these methods have overloads that allow them to be invoked in several different ways.

20.2.2. StringAssert

The StringAssert class does not provide any additional functionality that cannot be achieved with one or more assertions via the Assert class. However, it not only simplifies the test case code by making it clear that String assertions are being made; it also reduces the mundane tasks associated with testing for particular conditions. The additional assertions are as follows:

  • Contains: Tests whether a String contains another String

  • DoesNotMatch: Tests whether a String does not match a regular expression

  • EndsWith: Tests whether a String ends with a particular String

  • Matches: Tests whether a String matches a regular expression

  • StartsWith: Tests whether a String starts with a particular String

20.2.3. CollectionAssert

Similar to the StringAssert class, CollectionAssert is a helper class that is used to make assertions about a collection of items. Some of the assertions are as follows:

  • AllItemsAreNotNull: Tests that none of the items in a collection is a null reference

  • AllItemsAreUnique: Tests that there are no duplicate items in a collection

  • Contains: Tests whether a collection contains a particular object

  • IsSubsetOf: Tests whether a collection is a subset of another collection

20.2.4. ExpectedException Attribute

Sometimes test cases have to execute paths of code that can cause exceptions to be raised. While exception coding should be avoided, there are conditions where this might be appropriate. Instead of writing a test case that includes a Try-Catch block with an appropriate assertion to test that an exception was raised, you can mark the test case with an ExpectedException attribute. For example, change the CurrentStatus property to throw an exception if the PaidUp date is prior to the date the subscription opened, which in this case is a constant:

Public Const SubscriptionOpenedOn As Date = #1/1/2000#
    Public ReadOnly Property CurrentStatus() As Status
        Get
            If Not Me.PaidUpTo.HasValue Then Return Status.Temporary
            If Me.PaidUpTo.Value > Now Then
                Return Status.Financial
            Else
                If Me.PaidUpTo >= Now.AddMonths(-3) Then
                    Return Status.Unfinancial
                ElseIf Me.PaidUpTo >= SubscriptionOpenedOn Then
                    Return Status.Suspended
                Else
                    Throw New
ArgumentOutOfRangeException("Paid up date is not valid as it is before the
subscription opened")
                End If
            End If
        End Get
    End Property

Using the same procedure as before, you can create a separate test case for testing this code path, as shown in the following example:

<TestMethod()> _

    <ExpectedException(GetType(ArgumentOutOfRangeException), _
           "Argument exception not raised for invalid PaidUp date")> _
    Public Sub CurrentStatusExceptionTest()
        Dim target As Subscription = New Subscription

        target.PaidUpTo = Subscription.SubscriptionOpenedOn.AddMonths(-1)
        Dim val As Subscription.Status = Subscription.Status.Temporary

        Assert.AreEqual(val, target.CurrentStatus, _
              "This assertion should never actually be evaluated")
    End Sub

The ExpectedException attribute not only catches any exception raised by the test case; it also ensures that the type of exception matches the type expected. If no exception is raised by the test case, this attribute will fail.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.237.24