Translate

Tuesday, August 9, 2011

Implementing Rhino Mocks Using Visual Studio with Repository and Service Test Cases

Implementing Rhino Mocks Using Visual Studio with Repository


and Service Test Cases



This is an Example used for to explain about how to create Repository and Service Test cases using Rhino Mocks




Common Objects

EmployeeFilter

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UniversityEmployeeInformation.CommonObjects
{
public class EmployeeFilter
{
public int EmployeeId { get; set; }
public string EmployeeDept { get; set; }
}
}

MessageException



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;


namespace UniversityEmployeeInformation.CommonObjects
{

public class MessageException : Exception
{
public MessageException(string message)
: base(message)
{

}

}


}

ServiceFault


using System.Runtime.Serialization;


namespace UniversityEmployeeInformation.CommonObjects
{
[DataContract]
public class ServiceFault
{
[DataMember]
public MessageException FaultException { get

; set; }




}
}

UniversityEmployeeDo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UniversityEmployeeInformation.CommonObjects
{
public class UniversityEmployeeDo
{
public int EmployeeId { get; set; }

public string EmployeeName{get;set;}
public string EmployeeDepartment { get; set; }


}
}

UniversityEmployeeDTO

using System;
using System.Runtime.Serialization;
using System.Collections.Generic;

namespace UniversityEmployeeInformation.CommonObjects
{


public class UniversityEmployeeDTO
{
private List _employees;

public List Employees
{
get { return _employees; }
set { _employees = value; }
}
}
}

UniversityEmployeeRepository

Interface

UniversityEmployeeRep
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversityEmployeeInformation.CommonObjects;

namespace UniversityEmployeeInformation.UniversityEmployeeRepository.Interface
{
public interface IUniversityEmployeeRep
{
List GetEmployees(EmployeeFilter employeeFilter);
UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter, UniversityEmployeeDo employeeDo);
}
}

UniversityEmployeeRep

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversityEmployeeInformation.CommonObjects;
using System.Data.SqlClient;
using UniversityEmployeeInformation.UniversityEmployeeRepository.Interface;

namespace UniversityEmployeeInformation.UniversityEmployeeRepository
{
public class UniversityEmployeeRep : IUniversityEmployeeRep
{

public List GetEmployees(EmployeeFilter employeeFilter)
{
List employees = new List();
SqlConnection con =
new SqlConnection("Data Source=XYZ;Initial Catalog=EmployeeDB;Integrated Security=True");
con.Open();
string commandText = "select * from dbo.Employee where EmployeeId=" + employeeFilter.EmployeeId;
SqlCommand cmd = new SqlCommand(commandText, con);
SqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.Read())
{
UniversityEmployeeDo employeeDo = new UniversityEmployeeDo();
employeeDo.EmployeeId = Convert.ToInt32(dr["EmployeeId"]);
employeeDo.EmployeeDepartment = dr["EmployeeName"].ToString();
employeeDo.EmployeeName = dr["EmployeeDepartment"].ToString();
employees.Add(employeeDo);
}
return employees;
}

public UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter, UniversityEmployeeDo employeeDo)
{
throw new NotImplementedException();
}
}
}


UniversityManager

Interfacce

IUniversityEmployeeManager
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversityEmployeeInformation.CommonObjects;

namespace UniversityEmployeeInformation.Manager.Interface
{
public interface IUniversityEmployeeManager
{
List GEmployees(EmployeeFilter employeeFilter);
}
}

UniversityEmployeeManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversityEmployeeInformation.CommonObjects;
using UniversityEmployeeInformation.UniversityEmployeeRepository;
using UniversityEmployeeInformation.UniversityEmployeeRepository.Interface;
using UniversityEmployeeInformation.Manager.Interface;


namespace EmployeeInformation.Manager
{
public class UniversityEmployeeManager:IUniversityEmployeeManager
{
private IUniversityEmployeeRep _employee;

public IUniversityEmployeeRep Employee
{
set { _employee = value; }
}
public List GEmployees(EmployeeFilter employeeFilter)
{
_employee = new UniversityEmployeeRep();
return _employee.GetEmployees(employeeFilter);
}
}
}

Let me create the service

UniversityEmployeeService

Interface
IUniversityEmployeeService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using UniversityEmployeeInformation.CommonObjects;
using UniversityEmployeeInformation.UniversityEmployeeRepository;


namespace EmployeeInformation.EmployeeService.Interface
{
// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in App.config.
[ServiceContract]
public interface IUniversityEmployeeService
{
[OperationContract]
[FaultContract(typeof(ServiceFault))]
List GetEmployees(EmployeeFilter employeeFilter);


[OperationContract]
[FaultContract(typeof(ServiceFault))]
UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter);
}


// Use a data contract as illustrated in the sample below to add composite types to service operations

}

UniversityEmployeeService


using System;
using System.Collections.Generic;
using System.ServiceModel;
using UniversityEmployeeInformation.CommonObjects;
using EmployeeInformation.EmployeeService.Interface;
using UniversityEmployeeInformation.UniversityEmployeeRepository;
using UniversityEmployeeInformation.UniversityEmployeeRepository.Interface;
using UniversityEmployeeInformation.Manager.Interface;


namespace UniversityEmployeeInformation.UniversityEmployeeService.Service
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in App.config.
public class UniversityEmployeeService : IUniversityEmployeeService
{
private IUniversityEmployeeRep _employeeRepository;
private ServiceFault _fault;

public UniversityEmployeeService()
{
_employeeRepository = new UniversityEmployeeRep();

}
public UniversityEmployeeService(IUniversityEmployeeRep employee)
{
_employeeRepository = employee;
}
private IUniversityEmployeeManager _employeeManager;
public List GetEmployees(EmployeeFilter employeeFilter)
{

return _employeeRepository.GetEmployees(employeeFilter);
}

public UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter)
{
try
{



if (employeeFilter.EmployeeId <= 0) { throw new MessageException("Invalid EmployeeId"); } UniversityEmployeeDo employee = _employeeRepository.GetEmployees(employeeFilter)[0]; UniversityEmployeeDo employeeDo = _employeeRepository.UpdateEmployee(employeeFilter, employee); return employeeDo; } catch (Exception ex) { _fault = new ServiceFault(){FaultException = (MessageException) ex}; throw new FaultException(_fault, new FaultReason(string.Empty));
}

}


}
}


Let us create Service Test Project
UniversityEmployeeServiceTest

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.ServiceModel;
using System.Text;
using UniversityEmployeeInformation.CommonObjects;
using System.Data.SqlClient;
using UniversityEmployeeInformation.UniversityEmployeeService.Service;

using NUnit;
using NUnit.Framework;
using Rhino.Mocks;
using UniversityEmployeeInformation.UniversityEmployeeRepository;
using UniversityEmployeeInformation.UniversityEmployeeRepository.Interface;

namespace UniversityEmployeeServiceTest
{

[TestFixture, System.ComponentModel.Description("EmployeeRepository Test")]
public class UniversityEmployeeServiceTest
{
private MockRepository _mockRepository;
private UniversityEmployeeService _employeeService;
private ServiceFault _fault;

[TestFixtureTearDown]
public void TestFixtureTearDown()
{

}

[SetUp]
public void Initialize()
{

_employeeService = new UniversityEmployeeService { };
_mockRepository = new MockRepository();
}

[Test]
public void GetEmployeeServiceIntegrationTest()
{
EmployeeFilter employeeFilter = new EmployeeFilter();
employeeFilter.EmployeeId = 1223;
_employeeService = new UniversityEmployeeService();
List employees = _employeeService.GetEmployees(employeeFilter);
Assert.IsNotNull(employees);
}
[Test]
public void GetEmployee_ReturnsExpected_Employee()
{
var employees = new List();
var employeeDo1 = new UniversityEmployeeDo();
var employeeDo2 = new UniversityEmployeeDo();
employeeDo1.EmployeeId = 1223;
employeeDo1.EmployeeName = "ABC";
employeeDo1.EmployeeDepartment = "XYZ";
employeeDo2.EmployeeId = 123443;
employeeDo2.EmployeeName = "XYZ";
employeeDo2.EmployeeDepartment = "HIK";
employees.Add(employeeDo1);
employees.Add(employeeDo2);

var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(employees);

}
_mockRepository.ReplayAll();
List employeesResult = _employeeService.GetEmployees(employeeFilter);
_mockRepository.VerifyAll();
Assert.AreSame(employees, employeesResult);

}

[Test]
public void GetEmployee_ReturnsNotExpected_Employee_ServiceMockTest()
{
var actualemployees = new List();
var returnemployees = new List();
var employeeDo1 = new UniversityEmployeeDo();
var employeeDo2 = new UniversityEmployeeDo();
employeeDo1.EmployeeId = 1223;
employeeDo1.EmployeeName = "ABC";
employeeDo1.EmployeeDepartment = "XYZ";
employeeDo2.EmployeeId = 123443;
employeeDo2.EmployeeName = "XYZ";
employeeDo2.EmployeeDepartment = "HIK";
returnemployees.Add(employeeDo1);
actualemployees.Add(employeeDo2);
actualemployees.Add(employeeDo2);
var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { EmployeeId = 123443 };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(returnemployees);

}
_mockRepository.ReplayAll();
List employeesResult = _employeeService.GetEmployees(employeeFilter);
_mockRepository.VerifyAll();
Assert.AreNotEqual(actualemployees, employeesResult);

}

[Test]
public void UpdateEmployee_Will_Return_EmployeeDo_with_Updates()
{

var inputEmployeeDo = new UniversityEmployeeDo();
List employeeList = new List();
var updatedEmployeeDo = new UniversityEmployeeDo();
inputEmployeeDo.EmployeeId = 1223;
inputEmployeeDo.EmployeeName = "ABC";
inputEmployeeDo.EmployeeDepartment = "BPO";
updatedEmployeeDo.EmployeeId = 1223;
updatedEmployeeDo.EmployeeName = "ABC";
updatedEmployeeDo.EmployeeDepartment = "DEVELOPMENT";
employeeList.Add(inputEmployeeDo);
var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { EmployeeId = 123 };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(employeeList);
Expect.Call(mockEmployeeRepository.UpdateEmployee(employeeFilter, inputEmployeeDo)).Return(updatedEmployeeDo);

}
_mockRepository.ReplayAll();
UniversityEmployeeDo employee
= _employeeService.UpdateEmployee(employeeFilter);
_mockRepository.VerifyAll();

Assert.AreSame(updatedEmployeeDo.EmployeeDepartment, employee.EmployeeDepartment);
}


[Test]
[ExpectedException(typeof(MessageException), ExpectedMessage = "Invalid EmployeeId")]
public void Update_Employee_will_Return_Excception_If_The_EmployeeId_Is_Less_than_OR_equalToZero()
{
try
{
var inputEmployeeDo = new UniversityEmployeeDo();
List employeeList = new List();
var updatedEmployeeDo = new UniversityEmployeeDo();
inputEmployeeDo.EmployeeId = 1223;
inputEmployeeDo.EmployeeName = "ABC";
inputEmployeeDo.EmployeeDepartment = "BPO";
updatedEmployeeDo.EmployeeId = 1223;
updatedEmployeeDo.EmployeeName = "ABC";
updatedEmployeeDo.EmployeeDepartment = "DEVELOPMENT";
employeeList.Add(inputEmployeeDo);
var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { EmployeeId = -1235 };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(employeeList);
Expect.Call(mockEmployeeRepository.UpdateEmployee(employeeFilter, inputEmployeeDo)).Return(updatedEmployeeDo);

}
_mockRepository.ReplayAll();
UniversityEmployeeDo employee
= _employeeService.UpdateEmployee(employeeFilter);
_mockRepository.VerifyAll();


}
catch (Exception ex)
{
throw ((System.ServiceModel.FaultException) (ex)).Detail.
FaultException;
}
}
}
}

This is a different kind of architecture where there will be Repository,Manager ,Comon Objects,DTOs and Service,
I used all these and created advance Mock Test cases for Service ,I used an example called UniversityEmployee Information
First part explains about the Domain Common Objects UniversityEmployeeDo which has the three properties

public int EmployeeId { get; set; }
public string EmployeeName{get;set;}
public string EmployeeDepartment { get; set; }
And also a EmployeeFilter Do with two Properties
public int EmployeeId { get; set; }
public string EmployeeDept { get; set; }
i also added MessageException and a DTO
UniversityEmployeeRepository
This is the Repository where we access the database or Update the database and so
I created an interface IUniversityEmployeeRep where i declared two methods
List GetEmployees(EmployeeFilter employeeFilter);
UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter, UniversityEmployeeDo employeeDo);

If you Observed the two Methods in implementation
The first one
public List GetEmployees(EmployeeFilter employeeFilter)
{
List employees = new List();
SqlConnection con =
new SqlConnection("Data Source=ABRAR-PC;Initial Catalog=EmployeeDB;Integrated Security=True");
con.Open();
string commandText = "select * from dbo.Employee where EmployeeId=" + employeeFilter.EmployeeId;
SqlCommand cmd = new SqlCommand(commandText, con);
SqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.Read())
{
UniversityEmployeeDo employeeDo = new UniversityEmployeeDo();
employeeDo.EmployeeId = Convert.ToInt32(dr["EmployeeId"]);
employeeDo.EmployeeDepartment = dr["EmployeeName"].ToString();
employeeDo.EmployeeName = dr["EmployeeDepartment"].ToString();
employees.Add(employeeDo);
}
return employees;
}

Here, I am returning the employee list fetching from the database,there is another method
public UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter, UniversityEmployeeDo employeeDo)
{
throw new NotImplementedException();
}
UpdateEmployee which is not yet implemented and it has NotImplementedException throw Exception

I am using these two repository methods directly in Service
I created Service called UniversityEmployeeService which is a WCF Service and has two methods
Interface:
// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in App.config.
[ServiceContract]
public interface IUniversityEmployeeService
{
[OperationContract]
[FaultContract(typeof(ServiceFault))]
List GetEmployees(EmployeeFilter employeeFilter);


[OperationContract]
[FaultContract(typeof(ServiceFault))]
UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter);
}
And In Service
private IUniversityEmployeeRep _employeeRepository;
private ServiceFault _fault;

public UniversityEmployeeService()
{
_employeeRepository = new UniversityEmployeeRep();

}
public UniversityEmployeeService(IUniversityEmployeeRep employee)
{
_employeeRepository = employee;
}
private IUniversityEmployeeManager _employeeManager;
public List GetEmployees(EmployeeFilter employeeFilter)
{

return _employeeRepository.GetEmployees(employeeFilter);
}

public UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter)
{
try
{



if (employeeFilter.EmployeeId <= 0) { throw new MessageException("Invalid EmployeeId"); } UniversityEmployeeDo employee = _employeeRepository.GetEmployees(employeeFilter)[0]; UniversityEmployeeDo employeeDo = _employeeRepository.UpdateEmployee(employeeFilter, employee); return employeeDo; } catch (Exception ex) { _fault = new ServiceFault(){FaultException = (MessageException) ex}; throw new FaultException(_fault, new FaultReason(string.Empty));
}

}
In Service I created Service constructor where I am going to inject the Mock Repository

In this Service I have two methods
1. GetEmployees
2. UpdateEmployee
Since i added Repository code in GetEmployee but i have not yet added and any logic in Updated Employee Repository method,but i create the update service method,i know what validations i need to put and check for the employee in Mock service Test case


Let us now work around the mock test cases
[Test]
public void GetEmployee_ReturnsExpected_Employee()
{
var employees = new List();
var employeeDo1 = new UniversityEmployeeDo();
var employeeDo2 = new UniversityEmployeeDo();
employeeDo1.EmployeeId = 1223;
employeeDo1.EmployeeName = "ABC";
employeeDo1.EmployeeDepartment = "XYZ";
employeeDo2.EmployeeId = 123443;
employeeDo2.EmployeeName = "XYZ";
employeeDo2.EmployeeDepartment = "HIK";
employees.Add(employeeDo1);
employees.Add(employeeDo2);

var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(employees);

}
_mockRepository.ReplayAll();
List employeesResult = _employeeService.GetEmployees(employeeFilter);
_mockRepository.VerifyAll();
Assert.AreSame(employees, employeesResult);

}

In this test case GetEmployee_ReturnsExpected_Employee will returns me the expected employee
I declare two Employees
var employeeDo1 = new UniversityEmployeeDo();
var employeeDo2 = new UniversityEmployeeDo(); and added to a list
and in Mock test i am asking return me only these two employees
and it will return me only these two employees without fetching it from the database because i mock the employee Repository Using
var mockEmployeeRepository = _mockRepository.StrictMock();

In this my test case will be always pass ,it will be failed if someone changes the logic in Service
There is another benefit of using mock is that I explain in the next test case
[Test]
public void UpdateEmployee_Will_Return_EmployeeDo_with_Updates()
{

var inputEmployeeDo = new UniversityEmployeeDo();
List employeeList = new List();
var updatedEmployeeDo = new UniversityEmployeeDo();
inputEmployeeDo.EmployeeId = 1223;
inputEmployeeDo.EmployeeName = "ABC";
inputEmployeeDo.EmployeeDepartment = "BPO";
updatedEmployeeDo.EmployeeId = 1223;
updatedEmployeeDo.EmployeeName = "ABC";
updatedEmployeeDo.EmployeeDepartment = "DEVELOPMENT";
employeeList.Add(inputEmployeeDo);
var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { EmployeeId = 123 };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(employeeList);
Expect.Call(mockEmployeeRepository.UpdateEmployee(employeeFilter, inputEmployeeDo)).Return(updatedEmployeeDo);

}
_mockRepository.ReplayAll();
UniversityEmployeeDo employee
= _employeeService.UpdateEmployee(employeeFilter);
_mockRepository.VerifyAll();

Assert.AreSame(updatedEmployeeDo.EmployeeDepartment, employee.EmployeeDepartment);
}

In this test case _ UpdateEmployee_Will_Return_EmployeeDo_with_Updates()
I am askign to update the employee and return me updated UniversityEmployeeDo

For Exception Test case we can write like this I created one test case
[Test]
[ExpectedException(typeof(MessageException), ExpectedMessage = "Invalid EmployeeId")]
public void Update_Employee_will_Return_Excception_If_The_EmployeeId_Is_Less_than_OR_equalToZero()
{

var inputEmployeeDo = new UniversityEmployeeDo();
List employeeList = new List();
var updatedEmployeeDo = new UniversityEmployeeDo();
inputEmployeeDo.EmployeeId = 1223;
inputEmployeeDo.EmployeeName = "ABC";
inputEmployeeDo.EmployeeDepartment = "BPO";
updatedEmployeeDo.EmployeeId = 1223;
updatedEmployeeDo.EmployeeName = "ABC";
updatedEmployeeDo.EmployeeDepartment = "DEVELOPMENT";
employeeList.Add(inputEmployeeDo);
var mockEmployeeRepository = _mockRepository.StrictMock();
_employeeService = new UniversityEmployeeService(mockEmployeeRepository);
var employeeFilter = new EmployeeFilter() { EmployeeId = -1235 };
using (_mockRepository.Ordered())
{
Expect.Call(mockEmployeeRepository.GetEmployees(employeeFilter)).Return(employeeList);
Expect.Call(mockEmployeeRepository.UpdateEmployee(employeeFilter, inputEmployeeDo)).Return(updatedEmployeeDo);

}
_mockRepository.ReplayAll();
UniversityEmployeeDo employee
= _employeeService.UpdateEmployee(employeeFilter);
_mockRepository.VerifyAll();



}

This Test case say throw MessageException if i passed a Invalid employee Id
Update_Employee_will_Return_Excception_If_The_EmployeeId_Is_Less_than_OR_equalToZero





Working Solution will be provide based on your demand
on comments

No comments:

Post a Comment