Using Moq, System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.ObjectProxy' to type

15,373

Your mock is of IActiveState, not ActiveStateElements.

When you call new Mock<IActiveState>() it is creating some new type on the fly that implements the interface IActiveState. This new type is not convertible to ActiveStateElements, which means the cast is gonna fail in the constructor.

You could create the mock like var moqElement = new Mock<ActiveStateElements>(), but I imagine that won't work. The methods on ActiveStateElements are likely not virtual, so you wouldn't be able to setup any of the methods.

The real issue is that ActiveStateElementBehavior says to consumers "I need something that implements IActiveState". And then internally it requires an instance of ActiveStateElements.

You should define whatever other methods that you need on IActiveState, and ActiveStateElementBehavior shouldn't have any casts or references to ActiveStateElements. It should only be aware of the interface IActiveState

Share:
15,373

Related videos on Youtube

Nikolay Advolodkin
Author by

Nikolay Advolodkin

Updated on September 16, 2022

Comments

  • Nikolay Advolodkin
    Nikolay Advolodkin over 1 year

    Can someone help me to fix this error message please? I don't understand why the cast doesn't work:

    Message: System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.ObjectProxy' to type 'Automation.Pages.ToolbarElements.ElementsWithActiveState.ActiveStateElements'.

    Here is my test:

    [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);
        }
    }
    

    Here is my code:

    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();
    }
    
    • Nkosi
      Nkosi about 6 years
      This demonstrates what happens when you violate Explicit Dependency Principle. It is bad design to ask for an interface only to cast it back to an implementation concern.
    • Nkosi
      Nkosi about 6 years
      The constructor is thus lying about what the class truly dependent on.
  • Nkosi
    Nkosi about 6 years
    Great answer and exactly on point as to what the OP did wrong.
  • Nikolay Advolodkin
    Nikolay Advolodkin about 6 years
    So should I expect the ActiveStateElements.cs instead of the IActiveState in my constructor? But then you are correct that I won't be able to test it doing this: var moqElement = new Mock<ActiveStateElements>()
  • Jai dewani
    Jai dewani about 3 years
    Suppose someone is stuck with the above codebase with the only difference being that ActiveStateElements is child class of IActiveState Interface. Can we use something else than FakeItEasy to do testing in this case?
  • FUR10N
    FUR10N about 3 years
    hmm, not sure, but I think it would be tough. The pattern in the original question is notoriously difficult to unit test and mock.