【问题标题】:Using Moq, System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.ObjectProxy' to type使用起订量,System.InvalidCastException:无法将“Castle.Proxies.ObjectProxy”类型的对象转换为类型
【发布时间】:2018-02-13 18:18:51
【问题描述】:

有人可以帮我解决这个错误信息吗?我不明白为什么演员表不起作用:

消息:System.InvalidCastException:无法转换类型的对象 'Castle.Proxies.ObjectProxy' 输入 'Automation.Pages.ToolbarElements.ElementsWithActiveState.ActiveStateElements'。

这是我的测试:

[TestFixture]
[Category("unit")]
class ActiveStateElementBehaviorTests
{
    [Test]
    public void GetCurrentElementState_StateIsActive_ReturnActive()
    {
        var moqElement = new Mock<IActiveState>();
        moqElement.Setup(x => x.IsElementInActiveState()).Returns(() => true);

        var behavior = new ActiveStateElementBehavior(moqElement.Object);
        behavior.GetCurrentElementState().Should().BeEquivalentTo(ElementState.Active);
    }
}

这是我的代码:

public class ActiveStateElementBehavior : IElementStateBehavior
{
    public ActiveStateElementBehavior(IActiveState toolbarElement)
    {
        Element = (ActiveStateElements)toolbarElement;
    }

    public ENAEPToolbarElement Element { get; }

    public ElementState GetCurrentElementState()
    {
        var element = (ActiveStateElements) Element;
        return element.IsElementInActiveState() ? ElementState.Active :
             element.IsButtonInEnabledState() ? ElementState.Default : 
             ElementState.Disabled;
    }
}

public interface IActiveState
{
    bool IsElementInActiveState();
}

【问题讨论】:

  • 这演示了当您违反显式依赖原则时会发生什么。仅要求接口将其转换回实现问题是糟糕的设计。
  • 构造函数因此对类真正依赖的内容撒谎。
  • 那么你是不是建议我应该将具体类型 ActiveStateElements 传递给构造函数?
  • 不,类应该依赖于抽象而不是具体化和实现问题。创建一个接口,提供必要的功能并让派生类封装所需的功能。
  • 你为什么要投给ActiveStateElements

标签: c# unit-testing mocking moq


【解决方案1】:

你的模拟是IActiveState,而不是ActiveStateElements

当您调用new Mock&lt;IActiveState&gt;() 时,它正在动态创建一些实现接口IActiveState 的新类型。 这种新类型不能转换为ActiveStateElements,这意味着强制转换在构造函数中会失败。

您可以创建像 var moqElement = new Mock&lt;ActiveStateElements&gt;() 这样的模拟,但我想这行不通。 ActiveStateElements 上的方法可能不是virtual,因此您将无法设置任何方法。

真正的问题是ActiveStateElementBehavior 对消费者说“我需要实现IActiveState 的东西”。然后在内部需要ActiveStateElements 的实例。

您应该在IActiveState 上定义您需要的任何其他方法,并且ActiveStateElementBehavior 不应有任何类型转换或对ActiveStateElements 的引用。它应该只知道接口IActiveState

【讨论】:

  • 很好的答案,并且准确地说明了 OP 做错了什么。
  • 那么我应该期望在我的构造函数中使用 ActiveStateElements.cs 而不是 IActiveState 吗?但是你是对的,我无法测试它: var moqElement = new Mock()
  • 假设有人坚持使用上面的代码库,唯一的区别是ActiveStateElementsIActiveState 接口的子类。在这种情况下,我们可以使用 FakeItEasy 以外的其他东西进行测试吗?
  • 嗯,不确定,但我认为这会很难。众所周知,原始问题中的模式很难进行单元测试和模拟。
猜你喜欢
  • 2013-11-18
  • 2020-04-16
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多