加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在使用监督控制器模式时,我应该如何使用Moq视图对我的WebF

发布时间:2020-12-15 21:30:08 所属栏目:百科 来源:网络整理
导读:我正在尝试测试使用ASP.NET WebFormsMVP创建的Presenter.我正在使用“监督控制器”模式构建它,因此View负责从模型中更新自身.我简化了以下带有文本框,按钮和按钮的页面示例.标签.您输入文本框按下按钮和文本HelloWorld! 你的文字被放在标签上. 下面的示例代
我正在尝试测试使用ASP.NET WebFormsMVP创建的Presenter.我正在使用“监督控制器”模式构建它,因此View负责从模型中更新自身.我简化了以下带有文本框,按钮和按钮的页面示例.标签.您输入文本框&按下按钮和文本HelloWorld! <你的文字>被放在标签上.

下面的示例代码,但简而言之:

> button_click将引发一个View Event.
> Presenter订阅此ViewEvent并捕获args(即消息)
> Presenter完成工作(字符串连接)并更新模型
>视图重新绑定到Model.Message属性&一切正常.

//Model
public class HelloWorldModel {
    public string Message { get; set; }
}

//Args
public class HelloWorldEventArgs : EventArgs {
    public string Message { get; set; }
}

//View
public interface IHelloWorldView : IView<HelloWorldModel> {
    event EventHandler<HelloWorldEventArgs> SendMessage;
}

//Presenter
public class HelloWorldPresenter : Presenter<IHelloWorldView> 
{
    private readonly EventHandler<HelloWorldEventArgs> SendMessageDelegate;

    public HelloWorldPresenter(IHelloWorldView view) : base(view)
    {
        SendMessageDelegate = ((s,e) => SendMessageReceived(e.Message));
        View.SendMessage += SendMessageDelegate;
    }

    public override void ReleaseView()
    {
        View.SendMessage -= SendMessageDelegate;
    }

    public void SendMessageReceived(string message)
    {
        View.Model.Message = string.Format("Hello World! - {0}",message);
    }
}

//View implementation
[PresenterBinding(typeof(HelloWorldPresenter))]
public partial class HelloWorld : MvpPage<HelloWorldModel>,IHelloWorldView
{
    protected void EchoButtonClick(object sender,EventArgs e)
    {
        if(SendMessage != null)
        {
            var args = new HelloWorldEventArgs {Message = MessageTextBox.Text};
            SendMessage(sender,args);
        }
    }

    public event EventHandler<HelloWorldEventArgs> SendMessage;
}

我的问题在于测试.

由于View负责从模型中更新自身,因此Presenter仅设置Model.Message属性…因此在单元测试中,我想执行以下操作.

>模仿我的IHelloWorldView
>用模拟实例化我的礼物.
>在Mock上触发事件
>验证当前是否设置了模拟的Model.Message属性.

[TestMethod]
public void TestMethod1()
{
    var input = "My Message";
    var expected = string.Format("Hello World! - {0}",input);

    var mock = new Mock<IHelloWorldView>
    {
        DefaultValue = DefaultValue.Mock
    };
    var pres = new HelloWorldPresenter(mock.Object);

    mock.Raise(m => 
        m.SendMessage += null,new HelloWorldEventArgs { Message = input });

    mock.VerifySet(view => 
        view.Model.Message = It.Is<string>(s => s == expected),Times.Once());
}

但这不会起作用,除非我明确地将我的模型的Message属性标记为虚拟,我真的不想这样做.例如

//Model
public class HelloWorldModel {
    public string Message { get; set; }
}

我的其他选项是使用被动视图模式并在IHelloWorldView上将asp:标签Text作为字符串属性公开,并直接从Presenter设置…然后我应该能够测试它.

>被动是否从测试的角度看待更好的方法?
>我是否有必要同时模拟我的模型(我不确定WebFormsMVP中是否可行?
要么
>我需要制作Model Virtual的所有属性
要么
>我错过了某个地方的观点吗?

解决方法

您正在使用DefaultValue.Mock设置view-mock,因此您的视图将具有初始化的Model属性.而不是使用Moq来检查模型的值,只需直接检查模型上的消息:

Assert.That(mock.Object.Model.Message,Is.EqualTo(expected));

这个小的(但在语义上相等)变化的美妙之处在于你的模拟突然变成了一个存根,你正在测试最终结果而不是细节的实现细节.至于你的问题,在可测试性方面设计你的系统是一件好事,但我不会开始虚拟化或接口所有东西只是为了使它对Moq友好;制作一个SOLID架构,不需要Moq-able.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读