Lennart
Lennart

Reputation: 10343

How can I test that an MVVM light message has been received and acted upon?

I have a derived class that gets an object via property injection and registers on the messenger of that object:

public class Foo : AbsFoo
{
    private IBar bar;
    public override IBar Bar 
    {
        get {return bar;}
        set
        {
            bar = value
            if(bar != null)
            {
                bar.Messenger.Register<MyMessage>(this, m => SomeMethod());
            }
        }
    }
    public override void SomeMethod()
    {
        //..
    }
}

Basically, I want to set Bar, send a message, and verify that SomeMethod() is called.

My test looks like this:

var fixture = new Fixture();
fixture.Customize(new AutoConfiguredMoqCustomization());
var messenger = new Messenger();

var barFixture = fixture.Create<IBar>();
barFixture.Messenger = messenger

var fooMock = new Mock<Foo> {CallBase = true};
fooMock.SetupAllProperties();
fooMock.Object.Bar = barFixture;
fooMock.VerifySet(s=> s.Bar = It.IsAny<IBar>(),Times.AtLeastOnce()); // Success

messenger.Send(new MyMessage());
fooMock.Verify(c => c.SomeMethod(), Times.Once);  // Fails   

VerifySet() succeeds, and the correct object is passed in (checked via debugging), and the messenger instances are the same. But the Verifyon the method call fails, and I don't really understand why.

I'm not quite sure about the setup methods I have to use (Setup? SetupSet? Another?) on fooMock

Upvotes: 4

Views: 658

Answers (1)

Michal Ciechan
Michal Ciechan

Reputation: 13888

Remove your call to

        fooMock.SetupAllProperties();

This causes the Mock to override the property, and your Register method never gets called in the setter.

Code that the above line causes never to be run (As it is overridden to custom implementation)

        public override IBar Bar
        {
            get { return _bar; }
            set
            {
                _bar = value;
                _bar?.Messenger.Register<MyMessage>(this, m => SomeMethod());
            }
        }

Therefore you never subscribe to any messages on the messenger.

EDIT

The following work for me:

        var messenger = new Messenger();

        var bar = new Mock<Foo.IBar>();
        bar.Setup(x => x.Messenger).Returns(messenger);

        var fooMock = new Mock<Foo> { CallBase = true };
        //fooMock.SetupAllProperties();
        fooMock.Object.Bar = bar.Object;
        fooMock.VerifySet(s => s.Bar = It.IsAny<Foo.IBar>(), Times.AtLeastOnce()); // Success


        messenger.Send(new Foo.MyMessage());
        fooMock.Verify(c => c.SomeMethod(), Times.Once);  // Works

One thing you may need to do is the following before you send the message to tell Moq to register calls:

fooMock.Setup(x => x.SomeMethod()).Verifiable();

Upvotes: 5

Related Questions