views:

178

answers:

1

I have a simple unit test which tests that a validation function picks up a specific validation issue. The validation item returns a simple object with Item & Message properties. I've written a unit test for this function but this always fails even though I know the function works as expected.

<TestMethod()> Public Sub ContractNote_ValidateForManualInputTest_TradeOrderValueComparison()

    'Can't get this test to work even though validation works!
    Dim CN As ContractNote = New ContractNote
    Dim Trade As New TradeOrder

    Trade.TradeValue = 100

    With CN
        .CNTradeDate = Date.Today
        .CNTradePrice = 1
        .CNTradeUnits = 1
        .CNTradeValue = 1
        .FundManagerReference = "_zzz_"
        .SkandiaCompanyOrderID = "xxx"
        .ParentTradeOrder = Trade
    End With

    Dim ActualItems As System.Collections.Generic.List(Of ValidationItem) =       CN.ValidateForManualInput  

    If actualitems.Count > 0 Then             
        Dim item As ValidationItem = New ValidationItem("Value", "Must match trade value")
        CollectionAssert.Contains(ActualItems, item, "")
    End If

    Assert.AreNotEqual(0, ActualItems.Count)

End Sub

I've implemented IComparable on ValidationItem (I have a separate unit test which confirms this works). Am I Using CollectionAssert correctly?

+2  A: 

The MSDN doc for CollectionAssert.Contains(collection,element,message) says:

Verifies that the specified collection contains the specified element. The assertion fails if the element is not found in the collection. Displays a message if the assertion fails.

Assuming CN.ValidateForManualInput returns a List of ValidationItems in ActualItems, let me call those items "A", "B" and "C" for a moment.

Next you create a new ValidationItem, constructing it with "Value" and "Must match trade value". Let me call this new ValidationItem "D" for a moment.

I think that your problem may be that your call to CollectionAssert.Contains() effectively says:

Assert that D is in the list that has only 3 items in it, A, B and C.

But it isn't, so the test fails.

What if, instead of CollectionInsert.Contains(), you loop over all the items in ActualItems and check each with something like:

Assert (ActualItems[ii].message is Not "Must match trade value")

(That may not be exact VB syntax. I usually write C#.)

JeffH
Thanks, but surely this works as long as there is only one item in the collection? Otherwise aren't you asserting that ALL the items have a matching message?
Simon
It's not a question of having a matching message. It is looking for the *specific* instance of your message object. Think of it this way: imagine A, B, C and D in my answer above are pound notes. Take a pen and write an X on pound note D. The statement "Contains(D)" doesn't ask: "Is there *a* pound note in the list that contains A, B, and C?" But rather: "Is this *specific* pound note (the one you wrote the X on) in the list?" The answer is no, so Contains() returns false. More clear?
JeffH