I have to test few different classes with very similar functionality.
All of them are injected with different interfaces, and all these interfaces have one or more methods with this signature:
string DoSomething1(string);
Many of the classes under test will call these interface methods, and I need to test how they respond to returning null, empty string and throwing exception. I.e. if it was only one class, I would have this test:
//arrange
CarComponentType carNull = new CarComponentType();
carNull.VendorCode = RESPONSE_NULL_CODE;
CarComponentType carEmpty = new CarComponentType();
carEmpty.VendorCode = RESPONSE_EMPTY_CODE;
CarComponentType carEx = new CarComponentType();
carEx.VendorCode = RESPONSE_EXCEPTION;
ICarDBCorrector dbCar = MockRepository.GenerateMock<ICarDBCorrector>();
dbCar
.Stub(d => d.GetCarVendorByCode(RESPONSE_NULL_CODE))
.Return(null);
dbCar
.Stub(d => d.GetCarVendorByCode(RESPONSE_EMPTY_CODE))
.Return(String.Empty);
dbCar
.Stub(d => dbCar.GetCarVendorByCode(RESPONSE_EXCEPTION))
.Throw(new Exception());
CarComponentCorrector corrector = new CarComponentCorrector(dbCar);
//act
corrector.CorrectComponent(carNull);
corrector.CorrectComponent(carEmpty);
corrector.CorrectComponent(carEx);
//assert
Assert.AreEqual(RESPONSE_NULL_CODE, carNull.VendorName);
Assert.AreEqual(RESPONSE_EMPTY_CODE, carEmpty.VendorName);
Assert.AreEqual(RESPONSE_EXCEPTION, carEx.VendorName);
Now, I have 2 more such a methods in ICarDBCorrector, and I'd prefer not to duplicate the testing code.
Also, I have few other ComponentCorrector classes, which use similar IDbXXX interfaces to do their job.
So, I was thinking about creating some generic method, which can return the right stubbed mock to use, but I can not figure out how exactly to do this.
I.e. I'd like to have something like:
T PrepareNullEmptyThrowCorrector<T>(Action<T> action)
{
T mock = MockRepository.GenerateMock<T>();
mock.Stub(with null).Return(null)
///etc.
return mock;
}
Any idea how to approach this?
Thanks
UPDATE: I found some solution to my problem. But in order to have more "scientific" answer, I'd prefer a response with a solution for generic method, as I initially intended. Just curious. I'll change the "accepted answer" mark from my answer to any other, which offers another interesting solution.
I could not figure this out, but worked around it by creating a base class for all my test classes, and put in this base class a method, which returns the right thing, based on the input.
Then, in the tests themselves, instead of using Stub to retunr a value, I used Do() like this:
base test class:
protected string TestWithNullEmptyException(string code)
{
switch (code)
{
case REQ_NULL_CODE:
return null;
break;
case REQ_EMPTY_CODE:
return String.Empty;
break;
case REQ_EXCEPTION:
throw new Exception("Exception code recieved.");
break;
default:
return "UNDEFINED";
break;
}
}
And the in the tests:
dbCar
.Stub(d => d.GetAirVendorNameByCode(Arg<string>.Is.Anything))
.Do( (Func<string, string>)TestWithNullEmptyException );
That way, the only thing I need to repeat in each test case is the "stub", but I have to do it anyway.