0

I am trying to check Dictionary of type custom class as Value.

I would like to know if my approach of searching for value within Dictionary is correct using ContainValue in Fluent Assertion.

Here is the code

    public static void VerifyDictionary()
    {
        try
        {
            Dictionary<int, Employee> empDict = new Dictionary<int, Employee>
            {
                { 1, new Employee() {EmployeeID = 100,Name="Karthik", EmployeeEmail="karthik@executeautomation.com", EmployeeAddress="Chennai,India"}},
                {2, new Employee() { EmployeeID = 101,Name="Jack",EmployeeEmail="Jack@jill.com",EmployeeAddress="CA"} },
                {3, new Employee() { EmployeeID=102,Name="Sam",EmployeeEmail="Sam@sung.com",EmployeeAddress="SFO"}},
                {4, new Employee() { EmployeeID=103,Name="Max",EmployeeEmail="micro@max.com",EmployeeAddress="India" }}
            };

            empDict.Should().ContainValue(new Employee() { EmployeeID = 10, EmployeeEmail = "micro@max.com", EmployeeAddress = "India", Name = "Max" }, "because thats the information I need");


        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

Employee Class

public class Employee
{
    public int EmployeeID { get; set; }
    public string Name { get; set; }
    public string EmployeeEmail { get; set; }
    public string EmployeeAddress { get; set; }
}

While I execute this code, I am getting exception as shown

**

Expected dictionary {[1, BDDDemo.Employee], [2, BDDDemo.Employee], [3, BDDDemo.Employee], [4, BDDDemo.Employee]} to contain value 
BDDDemo.Employee
{
   EmployeeAddress = "India"
   EmployeeEmail = "micro@max.com"
   EmployeeID = 10
   Name = "Max"
} because thats the information I need.

**

Please help me understand whats wrong I am doing here.

Thanks,

Jose
  • 1,857
  • 1
  • 16
  • 34
Karthik KK
  • 38
  • 5
  • Are you using Fluent Assertion in some context outside of Unit Testing? I ask because with a unit testing framework traditionally you wouldn't catch the exception but would instead let the Test Runner handle it as a failure. – vossad01 Jun 19 '14 at 00:24
  • @vossad01- Actually I am running fluent assertion in normal C# console application project, I am not using any test framework like MSTest or NUnit here. Just to see if the Fluent Assertion really works for my needs – Karthik KK Jun 19 '14 at 01:18

1 Answers1

1

ContainValue's check for whether a value is in the dictionary or not is based on the Equals method of values in the dictionary.

In this case Employee does not override Equals so the implementation inherited from Object is used; that is reference equality will be used.

As an example, the following code would pass:

var expected = new Employee { EmployeeID = 10 };
var dictionary = new Dictionary<int, Employee> { {1, expected} };
dictionary.Should().ContainValue( expected );

This, however, would fail because they are two different instances of Employee even though all their members are the same:

var expected = new Employee { EmployeeID = 10 };
var dictionary = new Dictionary<int, Employee> { {1, expected} };
dictionary.Should().ContainValue( new Employee { EmployeeID = 10 } );

To make this later case pass you could override Equals. However, the entire class is mutable so I cannot recommend that unless you also make whichever member(s) you are using to determine Equality immutable.

Without modifying the class, your best bet is to use a different assertion, probably along these lines:

dictionary.Values.Should().Contain(employee => 
    /* Logic for how you want to determine a match */);
vossad01
  • 11,552
  • 8
  • 56
  • 109
  • Thank you so much Vossad01, The approach `empDict.Values.Should().Contain(a => a.EmployeeID == 102);` worked fine. Instead of dictionary I replaced that to empDict (I know thats what you meant). The answer was very explanatory and helped me a lot. Thanks a ton !!! – Karthik KK Jun 19 '14 at 01:32