Hi Mitesh,
I am trying to figure out similar but what I am finding so far is following:
1. A unit test should not touch the system, so any registry, IO, service, database, etc calls fall into integration tests rather than unit tests
2. So, the way I understand this is done is to create an interface defining what functionality is expected, and a class implementing that interfaced. Then your unit test will mock the interface, while your real code will instantiate the class. As an example, I have added code from a dummy little app which does similar with registry.
namespace ConsoleRhinoApp.RegistryActions
{
/// <summary>
/// Interface that can be used with both real project and unit tests.
/// </summary>
public interface IRegistryActions
{
string ReadValue(string path, string key);
bool WriteValue(string path, string key, string newSubKey, string value);
}
}
namespace ConsoleRhinoApp.RegistryActions
{
/// <summary>
/// Class to write / read registry.
/// Implements IRegistryActions interface we can use in real project or unit tests.
/// </summary>
public class RegistryActions : IRegistryActions
{
public string ReadValue(string path, string key)
{
var val = (string)Registry.LocalMachine.OpenSubKey(path).GetValue(key);
return val;
}
public bool WriteValue(string path, string key, string newSubKey, string value)
{
RegistryKey rt = null;
using (rt = Registry.LocalMachine.OpenSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree))
{
using (var sdp = rt.CreateSubKey(key))
{
sdp.SetValue(newSubKey, value);
}
}
return rt != null;
}
}
}
/// <summary>
/// This simmulates a real project.
/// REGISTRY KEY: HKLM\SOFTWARE\WOW6432Node\Mine\Location
/// If key does exist, it will add another key "RhinoTest".
/// Under this key, it will add new property "SomeDummyProperty"
/// And it will set this property to "Some dummy value"
/// </summary>
namespace ConsoleRhinoApp
{
public class Program
{
static void Main(string[] args)
{
string path = @"SOFTWARE\WOW6432Node\Mine\Location";
string key = "RhinoTest";
string newSubKey = "SomeDummyProperty";
string value = "Some dummy value";
// Create instance of class that reads/writes registry and pass it into class that uses it.
IRegistryActions ra = new RegistryActions.RegistryActions();
ExampleClass ec = new ExampleClass(ra);
if (ec.WriteValue(path, key, newSubKey, value))
{
Console.WriteLine(string.Format("Created new registry value"));
string newValue = ec.ReadValue(path + "\\" + key, newSubKey);
Console.WriteLine(string.Format("New registry value is \'{0}\'.", newValue));
}
Console.ReadKey();
}
}
}
And here is unit test
using System;
using NUnit.Framework;
using Rhino.Mocks;
using SystemWrapper.Microsoft.Win32;
using ConsoleRhinoApp.RegistryActions;
namespace UnitTestProject
{
[TestFixture]
public class UnitTest1
{
string path = @"SOFTWARE\WOW6432Node\Mine\Location";
string key = "RhinoTest";
string newSubKey = "SomeDummyProperty";
string value = "Some dummy value";
[Test]
public void Test_RegistryActions_generate_stub()
{
// Dynamically create a class that implements IRegistryAccess
var stub = MockRepository.Mock<IRegistryActions>(); // GenerateStub<IRegistryActions>();
var env = MockRepository.Mock<OperatingSystem>();
env.Stub(s => s.Platform).Return(PlatformID.Win32NT);
env.AssertWasCalled(s => s.Version);
}
[Test]
public void Test_RegistryActions_Write_should_return_true()
{
var stub = MockRepository.Mock<IRegistryActions>(); // GenerateStub<IRegistryActions>();
bool expected = true;
bool actual = true;
stub.Stub(s => s.WriteValue(path, key, newSubKey, value)).Return(expected);
stub.WriteValue(path, key, newSubKey, value).Equals(actual);
stub.AssertWasCalled(s => s.WriteValue(path, key, newSubKey, value));
Assert.AreEqual(expected, actual);
// Below is way to do Rhino's built in implementation, I use here our own implmentation which is RegistryActions
//IRegistryKeyWrap keyMock = MockRepository.GenerateMock<IRegistryKeyWrap>();
//keyMock.Stub(s => s.OpenSubKey(path + "\\" + key + "\\" + newSubKey, true)).Equals(true);
//keyMock.Stub(s => s.SetValue(newSubKey, value));
//keyMock.Stub(s => s.GetValue(newSubKey)).Return(value);
}
[Test]
public void Test_RegistryActions_Read_should_read_expected_value()
{
var stub = MockRepository.Mock<IRegistryActions>(); // GenerateStub<IRegistryActions>();
string expected = value;
string actual = value;
stub.Stub(s => s.ReadValue(path + "\\" + key, newSubKey)).Return(expected);
stub.ReadValue(path + "\\" + key, newSubKey).Equals(actual);
stub.AssertWasCalled(s => s.ReadValue(path + "\\" + key, newSubKey));
Assert.AreEqual(expected, actual);
}
}
}
Note that my unit test has reference to:
1. SystemWrapper v.0.4.0 by Vadim Kreyinin
2. RhinoMocks v.4.0.0-alpha3 by meisinger, ayende
Hope this helps, cheers