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
public List
{
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
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
{
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
}
}
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
{
_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
[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
{
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
}
}
}
}
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
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
_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
_mockRepository.VerifyAll();
Assert.AreNotEqual(actualemployees, employeesResult);
}
[Test]
public void UpdateEmployee_Will_Return_EmployeeDo_with_Updates()
{
var inputEmployeeDo = new UniversityEmployeeDo();
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
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
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
UniversityEmployeeDo UpdateEmployee(EmployeeFilter employeeFilter, UniversityEmployeeDo employeeDo);
If you Observed the two Methods in implementation
The first one
public List
{
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
[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
{
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
}
}
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
_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
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
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