Writing tests for CRUD controllers which follow this pattern.
- Get one or more parameters of various types from action method parameters
- Call some IEntityService.GetEntity(parameters from step 1) method
- If it returns null return NotFound
- Otherwise return the found object
I found myself writing very similar tests repeatedly.
[TestCase(true)]
[TestCase(false)]
public void GetsAccount(bool isExistingAccount)
{
const int accountId = -1;
var account = isExistingAccount ? new Account() : null;
A.CallTo(() => AccountService.GetAccount(accountId)).Returns(account);
var result = (IStatusCodeActionResult)_controller.GetAccount(accountId);
var statusCode = isExistingAccount ? HttpStatusCode.OK : HttpStatusCode.NotFound;
result.StatusCode.Should().Be((int)statusCode);
I attempted to write a generic method to fake.
public void GetEntityActionMethodTest<TEntityType>(bool isExisting, Func<int, TEntityType> serviceMethod, Func<int, ActionResult> actionMethod) where TEntityType : class
{
var fakeMethod = A.Fake<Func<int, TEntityType>>();
A.CallTo(() => fakeMethod(-1)).Returns( isExisting ? default(TEntityType) : null);
var result = (IStatusCodeActionResult)actionMethod(-1);
result.StatusCode.Should().Be(isExisting ? (int)HttpStatusCode.OK : (int)HttpStatusCode.NotFound);
}
There are two issues with it:
1) Does not fake correctly to return null
2) Assumes interface method has one integer parameter
Questions
1) Is it a good idea to work on creating a generic method that can fake methods that may have different signatures in different interfaces using FakeItEasy? How about with reflection?
2) If yes, how can I do that?
Thanks.