gpt4 book ai didi

c#-4.0 - FakeItEasy 的第一步和 Action 类型的问题

转载 作者:行者123 更新时间:2023-12-01 11:02:50 30 4
gpt4 key购买 nike

我有以下(这里是简化的)代码,我想用 FakeItEasy 进行测试.

public class ActionExecutor : IActionExecutor
{
public void TransactionalExecutionOf(Action action)
{
try
{
// ...
action();
// ...
}
catch
{
// ...
Rollback();
}
}

public void Commit()
{ }

public void Rollback()
{ }
}

public class Service : IService
{
private readonly IRepository _repository;

private readonly IActionExecutor _actionExecutor;

// ctor for CI

public void ServiceMethod(string name)
{
_actionExecutor.TransactionalExecutionOf(() =>
{
var item = _repository.FindByName(ItemSpecs.FindByNameSpec(name));
if (item == null) throw new ServiceException("Item not found");

item.DoSomething();
_actionExecutor.Commit();
}
}
}

我想测试是否抛出了 ServiceException,所以我这样设置我的测试

var repo = A.Fake<IRepository>();
A.CallTo(() => repo.FindByName(A<ISpec<Item>>.Ignored))
.Returns(null);

var executor = A.Fake<IActionExecutor>();
executor.Configure()
.CallsTo(x => x.Rollback()).DoesNothing();
executor.Configure()
.CallsTo(x => x.Commit()).DoesNothing();
executor.Configure()
.CallsTo(x => x.TransactionalExecutionOf(A<Action>.Ignored))
.CallsBaseMethod();

用下面的代码

var service = new Service(executor, repo);
service.ServiceMethod("notExists")
.Throws(new ServiceException());

我收到以下消息

The current proxy generator can not intercept the specified method for the following reason: - Sealed methods can not be intercepted.

如果我像这样直接在服务上调用方法

var service = new Service(executor, repo);
service.ServiceMethod("NotExists");

我收到这条消息

This is a DynamicProxy2 error: The interceptor attempted to 'Proceed' for method 'Void TransactionalExecutionOf(System.Action)' which has no target. When calling method without target there is no implementation to 'proceed' to and it is the responsibility of the interceptor to mimic the implementation (set return value, out arguments etc)

现在我有点迷茫,不知道下一步该做什么。

最佳答案

问题来自您创建假货的方式以及您以后期望它做什么:

var executor = A.Fake<IActionExecutor>();
// ...
executor.Configure()
.CallsTo(x => x.TransactionalExecutionOf(A<Action>.Ignored))
.CallsBaseMethod();

什么基本方法? FakeItEasy 不知道基类是什么,因此 DynamicProxy2 第二种情况下的异常。您可以通过这种方式创建部分模拟:

var executor = A.Fake<ActionExecutor>();

请注意,我们基于实际实现,不再是接口(interface)

然而,这引入了一组新问题,因为 ActionExecutor 上的方法不是虚拟的,因此拦截器无法很好地连接 - 拦截它们。要使当前设置正常工作,您必须更改 ActionExecutor 并将(所有)方法设为虚拟。

但是,您可能(甚至应该)希望避免修改现有代码(有时甚至可能不是一种选择)。然后,您可以像这样设置您的 IActionExecutor 假货:

var executor = A.Fake<IActionExecutor>();
A.CallTo(() => executor.TransactionalExecutionOf(A<Action>.Ignored))
.Invokes(f => new ActionExecutor()
.TransactionalExecutionOf((Action)f.Arguments.First())
);

这将允许您处理伪造的对象,但对 TransactionalExecutionOf 的调用除外,它将被重定向到实际实现。

关于c#-4.0 - FakeItEasy 的第一步和 Action 类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9053843/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com