【问题标题】:How can I test that an MVVM light message has been received and acted upon?如何测试是否已接收到 MVVM 轻消息并对其采取行动?
【发布时间】:2017-01-27 23:15:44
【问题描述】:

我有一个派生类,它通过属性注入获取对象并在该对象的信使上注册:

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()
    {
        //..
    }
}

基本上,我想设置Bar,发送消息,并验证SomeMethod() 是否被调用。

我的测试如下所示:

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()成功,传入了正确的对象(通过调试检查),messenger实例也一样。但是方法调用上的Verify失败了,我也不是很明白为什么。

我不太确定 fooMock 上必须使用的设置方法(Setup?SetupSet?另一个?)

【问题讨论】:

    标签: c# unit-testing moq mvvm-light autofixture


    【解决方案1】:

    删除您对

    的呼叫
            fooMock.SetupAllProperties();
    

    这会导致 Mock 覆盖该属性,并且您的 Register 方法永远不会在 setter 中被调用。

    上一行导致永远不会运行的代码(因为它被自定义实现覆盖)

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

    因此,您永远不会订阅 Messenger 上的任何消息。

    编辑

    以下工作适合我:

            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
    

    在发送消息以告诉 Moq 注册呼叫之前,您可能需要做以下事情:

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

    【讨论】:

    • 我做到了。现在 setter 被正确调用,注册成功,但是 Verify() 调用失败,Expected invocation on the mock once, but was 0 times: c =&gt; c.SomeMethod() No setups configured.
    猜你喜欢
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多