【问题标题】:mock an abstract method with the same signature as another method模拟与另一个方法具有相同签名的抽象方法
【发布时间】:2015-11-16 10:45:14
【问题描述】:

我有 2 个签名几乎相同的方法。唯一的区别是其中一个使用特定类型,另一个使用基类

public abstract class CommandHandlerBase<TCommand> : ICommandHandler<TCommand>
        where TCommand : CommandBase
{
    public int Id { get; }

    public CommandHandlerBase(int id)
    {
        this.Id = id;
    }

    public bool CanHandle(CommandBase command, Context context)
    {
        if (command.GetType() == typeof(TCommand))
            return CanHandle((TCommand)command, context);
        else
            return false;
    }

    public abstract bool CanHandle(TCommand command, Context context);

    public IEnumerable<EventBase> Handle(CommandBase command)
    {
        if (command.GetType() == typeof(TCommand))
            return Handle((TCommand)command);
        else
            throw new ArgumentException("The handler cannot handle the given command type");
    }

    public abstract IEnumerable<EventBase> Handle(TCommand command);
}

现在我试图断言如果命令类型是正确的类型,则调用特定方法。

这是我目前所拥有的:

var commandHandlerBaseMock = new Mock<CommandHandlerBase<TestCommand1>>(id);
commandHandlerBaseMock.CallBase = true;
var command = new TestCommand1();
commandHandlerBaseMock.Setup(ch => ch.CanHandle(command, null)).Returns(true);

bool result = commandHandlerBaseMock.Object.CanHandle(command, null);

result.Should().BeTrue();

问题在于 this 断言只是调用了被调用的方法,这根本没有帮助。实施永远不会受到影响。
有没有办法只模拟一个特定的方法重载?

【问题讨论】:

  • 测试什么都不做,因为这里的Act 部分只是调用了模拟本身的方法。考虑什么是您的测试系统并在测试中提供它的实例(实例不是模拟)并调用测试方法。如果被测系统有任何依赖关系,则模拟它们。这就是 mock 的用途。
  • @dee 我想避免仅仅为了测试而实现派生类。但看来我必须这样做......
  • IMO 创建可测试类没有错。有些人认为这是不好的做法,但我发现它多次有用。

标签: c# unit-testing moq


【解决方案1】:

这种代码结构是不可持续的......您正在添加 instanceOf 检查(通常是一个坏信号)并试图以多态方式隐藏签名。我希望 TCommand 类型的对象总是会在您的基类中命中 TCommand 特定实现。

如果您需要两个不同的处理程序,基于两种不同的类型,请考虑根本没有基类实现使用“告诉,不要问”原则并将处理推送到命令本身(您可以在抽象处理程序中使用“模板方法”模式来执行“通用的东西”),这意味着您不需要任何依赖于某些类型的基类中的专业代码。

【讨论】:

  • 感谢您的建议。两种接口都有不同的用途。非泛型用于通过公共接口访问对象,泛型用于针对强类型对象(而不是基类)进行编程。 CommandHandlerBase 只是将这两个类放在一起,这样就不必为每个实现编写相同的检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2013-04-16
  • 2011-10-25
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多