Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocked inner objects' events will not fire?

Using Moq with two interfaces,Outer and Inner, I am unable to get Outer.Inner.SomeEvent to fire.

public interface Outer
{
    Inner Inner { get; }
}

public interface Inner
{
    int Prop { get; set; }
    event EventHandler PropChanged;
}

public void Test()
{
    Mock<Outer> omock = new Mock<Outer>();
    Mock<Inner> imock = new Mock<Inner>();

    Console.WriteLine("Inner");
    imock.Object.PropChanged += InnerPropChanged;
    imock.Raise(m => m.PropChanged += null, EventArgs.Empty);
    imock.Object.PropChanged -= InnerPropChanged;

    // This has no effect.
    //omock.Setup(m => m.Inner).Returns(imock.Object);

    Console.WriteLine("Outer");
    // Both the auto recursive and the explicit above produce the same behavior.
    omock.SetupProperty(m => m.Inner.Prop, -1);
    omock.Object.Inner.PropChanged += InnerPropChanged;
    omock.Raise(m => m.Inner.PropChanged += null, EventArgs.Empty);
}

public void InnerPropChanged(object sender, EventArgs e)
{
    Console.WriteLine("  InnerPropChanged");
}

Output when calling Test():

Inner
  InnerPropChanged
Outer

How can I alert subscribers to any of Inner's events? Nothing seems to be able to fire them.

Edit - To clarify, I want to be able to raise the Inner event from the Outer context, so the final output should include:

Outer
  InnerPropChanged
like image 248
wes Avatar asked Dec 21 '25 16:12

wes


1 Answers

Maybe it's bug or a missing feature that the expression

omock.Raise(m => m.Inner.PropChanged += null, EventArgs.Empty);

is not working... however you can get the generated the Inner mock with Mock.Get and then you can raise the event on it:

public void Test()
{
    Mock<Outer> omock = new Mock<Outer>();
    Console.WriteLine("Outer");
    omock.SetupProperty(m => m.Inner.Prop, -1);
    omock.Object.Inner.PropChanged += InnerPropChanged;
    Mock.Get(omock.Object.Inner)
        .Raise(m => m.PropChanged += null, EventArgs.Empty);
}

Which produces your desired output:

Outer
  InnerPropChanged
like image 147
nemesv Avatar answered Dec 24 '25 04:12

nemesv