遵循此模式的CRUD控制器的书面测试。
我发现自己反复编写非常相似的测试。
[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);
我试图编写一种伪造的通用方法。
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);
}
有两个问题:
1)没有正确伪造以返回null
2)假设接口方法具有一个整数参数
问题
1)创建一个通用方法可以使用FakeItEasy伪造在不同接口中具有不同签名的方法,这是一个好主意吗?用反射怎么样?
2)是,我该怎么办?
谢谢。
答案 0 :(得分:0)
我不确定您的目标是什么。您说您正在尝试编写一种伪造的通用方法,但是您的示例看起来像是完整的测试。我将讨论如何伪造。将其纳入测试应该是很直接的。
如果目标是创建一个伪造品,该伪造品将在调用任何方法时返回特定对象,并由伪造品类型和返回值进行参数化,则可以使用FakeItEasy.Sdk namespace methods创建对象,然后可以配置respond to any method的伪造像这样:
public object CreateFakeWithReturnValue(Type typeOfFake, object returnValue)
{
var fake = Create.Fake(typeOfFake);
A.CallTo(fake).WithNonVoidReturnType().Returns(returnValue);
return fake;
}
当然,可以通过查看传入的调用来使此方法更加复杂(或者,如果您知道伪造的类型,则可以将该方法设为泛型,而仅使用标准的A.Fake
构造)。
正如@tom redfern所说,这并非在所有情况下都是最佳途径,但是您必须判断总体方法是否对您有意义。随着测试变得越来越复杂,您可能会发现自己对该方法进行了很多改进,以至于回到手工制作的假货变得更加有意义。