Moq和命令模式。我很难挣扎吗?

时间:2010-01-17 10:27:41

标签: tdd moq

TDD世界的新东西,我很快发现有时候嘲笑并不容易。 我们正在使用MOQ,所以我需要学习如何使用moq

我有一些使用命令模式的代码并且可以处理。但是如果要测试驱动它我不知道如何实现下面的代码。

我做了以下

  • 创建了BaseToolStripMenuItem:ToolStripMenuItem并添加了一个命令属性(见下文)
  • 创建一个窗体并添加了一个带有2项打开和退出
  • 的menuStrip

在我刚添加的表单中,将命令映射到一个按钮,所有这些都可以处理。

我想更改代码,以便我可以使用Moq进行UnitTest但是看不出来怎么???

你能帮忙吗?

有什么建议吗?

非常感谢!!

public interface ICommand
      {
        void Execute()
      }

       public abstract class BaseCmd :ICommand
       {
            protected ProcessMenuCommand ProcessCommand;
            protected MenuCommandFactory Factory;

            protected BaseCmd(ProcessMenuCommand processMenuCommand, MenuCommandFactory cmdfactory)
           {
              ProcessCommand = processMenuCommand;
              Factory = cmdfactory;
           }

           abstract public void Execute();
      }

    public class BaseToolStripMenuItem : ToolStripMenuItem
    {
         public BaseToolStripMenuItem()
         {
            Click += MenuItemClick;
            Command = null;
         }

         public BaseCmd Command { get; set; }

         private void MenuItemClick(object sender, EventArgs args)
         {
             if (Command != null) Command.Execute();
         }
    }
    public class MenuCommandFactory
    {
        private readonly ProcessMenuCommand _processMenuCommand;

        public MenuCommandFactory(ProcessMenuCommand processMenuCommand)
        {
            _processMenuCommand = processMenuCommand;
        }

        public OpenFileCmd OpenFile()
        {
            return  new OpenFileCmd(_processMenuCommand,this);
        }

        public ExitCmd Exit()
        {
            return new ExitCmd(_processMenuCommand, this);
        }
    }

    public class OpenFileCmd:BaseCmd
    {
        public OpenFileCmd(ProcessMenuCommand processMenu,MenuCommandFactory menuCommandFactory)
            :base(processMenu,menuCommandFactory)
        {
        }
        public override void Execute()
        {
            ProcessCommand.OpenFile();
        }
    }

    public class ProcessMenuCommand
    {
        public void OpenFile()
        {
            MessageBox.Show("Open a file");
        }

        public void Exit()
        {
            MessageBox.Show("Exiting");
        }
    }
    public class ExitCmd:BaseCmd
    {
        public ExitCmd(ProcessMenuCommand processMenu, MenuCommandFactory menuCommandFactory)
            :base(processMenu,menuCommandFactory)
        {
        }
        public override void Execute()
        {
            ProcessCommand.Exit();
        }
    }

    //In the form
    public partial class Form1 : Form
    {
        private ProcessMenuCommand menuCommandProcessor;
        private MenuCommandFactory factory;
        public Form1()
        {
            InitializeComponent();

            // Created editor and factory.
            menuCommandProcessor = new ProcessMenuCommand();
            factory = new MenuCommandFactory(menuCommandProcessor);

            // Get concrete command objects from factory and assign to corresponding menu items and tool strip buttons.
            tsOpen.Command = factory.OpenFile();
            tsExit.Command = factory.Exit();
        }
    }

2 个答案:

答案 0 :(得分:3)

  

但是,如果要试驾它我不知道如何实现下面的代码

关于TDD的想法是驱动你实现。有许多实现你可能永远不会使用TDD,所以你的问题并没有多大意义。

尝试编写一些测试,帮助您实现目标 您希望到达的解决方案的先入为主的图像。通常情况下,你最终会在一个与你原先想象的完全不同(和更好)的地方结束。

答案 1 :(得分:1)

一个简单的新手规则:没有抽象类。尝试仅使用接口和具体类重新设计。您会注意到测试结果会更容易。

对于“如何TDD命令对象”,Command只是一个提供单个动作的类。除了命名方法Execute()之外,以与测试驱动任何方法相同的方式对其进行试驾。