Hi there,
I wrote a test here and I'd like to know if this is the best way to do it. Essentially I have the following class:
public class MyClass
{
public Guid Id { get; set; }
public IDbCommand GetCommand()
{
IDbCommand command = this.MakeCommand();
command.CommandText = this.BuildQuery();
IDbDataParameter parameter = command.CreateParameter();
parameter.ParameterName = "@PK";
parameter.Value = this.Id;
command.Parameters.Add(parameter);
return command;
}
protected virtual IDbCommand MakeCommand()
{
return null; // will use a factory class here eventually...
}
public string BuildQuery()
{
return "some query...";
}
}
I want to test the GetCommand method, for which i have the following expectations:
* It must return a valid instance of an IDbCommand object;
* Its CommandText property has to be filled with whatever the BuildQuery method returns;
* It must have one "@PK" parameter;
* the "@PK" parameter's value must be MyClass' Id property.
At first I wrote the test using Reflective mocks, like so:
[TestMethod]
[VerifyMocks]
public void Test2()
{
string EXPECTED_QUERY = "SELECT PK_Contact, FirstName, LastName FROM Contacts " +
"WHERE FK_Company = @PK " +
"ORDER BY FirstName, LastName";
string EXPECTED_PK_PARAMETER_NAME = "@PK";
Guid EXPECTED_PK_VALUE = new Guid("8FB32696-BDB2-4CD7-880B-12A412D0C67A");
MockObject<IDbDataParameter> parameterMockBehavior = MockManager.MockObject<IDbDataParameter>();
parameterMockBehavior.ExpectSet("ParameterName").Args(EXPECTED_PK_PARAMETER_NAME);
parameterMockBehavior.ExpectSet("Value").Args(EXPECTED_PK_VALUE);
IDbDataParameter parameterMock = parameterMockBehavior.Object;
MockObject<IDataParameterCollection> parameterCollectionMockBehavior =
MockManager.MockObject<IDataParameterCollection>();
parameterCollectionMockBehavior.ExpectAndReturn("Add", 1).Args(parameterMock);
MockObject<IDbCommand> commandMockBehavior = MockManager.MockObject<IDbCommand>();
commandMockBehavior.ExpectAndReturn("CreateParameter", parameterMock);
commandMockBehavior.ExpectGet("Parameters", parameterCollectionMockBehavior.Object);
commandMockBehavior.ExpectSet("CommandText").Args(EXPECTED_QUERY);
Mock myClassMockBehavior = MockManager.MockAll<MyClass>();
myClassMockBehavior.ExpectAndReturn("MakeCommand", commandMockBehavior.Object);
myClassMockBehavior.ExpectAndReturn("BuildQuery", EXPECTED_QUERY);
MyClass myClass = new MyClass();
myClass.Id = EXPECTED_PK_VALUE;
IDbCommand command = myClass.GetCommand();
Assert.IsNotNull(command);
}
Then, I refactored the test so to use Natural mocks:
[TestMethod]
[VerifyMocks]
public void Test1()
{
string EXPECTED_QUERY = "SELECT PK_Contact, FirstName, LastName FROM Contacts " +
"WHERE FK_Company = @PK " +
"ORDER BY FirstName, LastName";
string EXPECTED_PK_PARAMETER_NAME = "@PK";
Guid EXPECTED_PK_VALUE = new Guid("8FB32696-BDB2-4CD7-880B-12A412D0C67A");
MockObject<IDbDataParameter> parameterMockBehavior = MockManager.MockObject<IDbDataParameter>();
IDbDataParameter parameterMock = parameterMockBehavior.Object;
MockObject<IDbCommand> commandMockBehavior = MockManager.MockObject<IDbCommand>();
IDbCommand commandMock = commandMockBehavior.Object;
using (RecordExpectations recorder = new RecordExpectations())
{
parameterMock.ParameterName = EXPECTED_PK_PARAMETER_NAME;
parameterMock.Value = EXPECTED_PK_VALUE;
commandMock.CommandText = EXPECTED_QUERY;
commandMock.CreateParameter();
recorder.Return(parameterMock);
commandMock.Parameters.Add(parameterMock);
recorder.Return(1);
}
Mock myClassMockBehavior = MockManager.MockAll<MyClass>();
myClassMockBehavior.ExpectAndReturn("MakeCommand", commandMock);
myClassMockBehavior.ExpectAndReturn("BuildQuery", EXPECTED_QUERY);
MyClass myClass = new MyClass&