在MVP GWT应用程序中测试演示者

时间:2011-07-07 14:04:31

标签: java unit-testing gwt mvp

我有一个简单的应用程序,并希望使其可测试。我是这个领域的新人。 这是一个简单的Presenter,请记住这段代码,你可以建议或给我一些如何测试它的例子。

    public class SomePresenter extends Presenter<MainPanelPresenter.Display>
    {

    public interface Display extends WidgetDisplay
    {
      HasClickHandlers getAddButton();

      HasClickHandlers getDeleteButton();

      void setData(ArrayList<Person> data);

      ArrayList<String> getSelectedRows();

      Widget asWidget();

    }

    private final DispatchAsync dispatcher;
    public static final Place PLACE = new Place("main");

    @Inject
    public SomePresenter(DispatchAsync dispatcher, EventBus eventBus, Display display)
    {
      super(display, eventBus);
      this.dispatcher = dispatcher;
      bind();
    }

    protected void onBind()
    {
      display.getAddButton().addClickHandler(new ClickHandler()
      {
        public void onClick(ClickEvent event)
        {
          eventBus.fireEvent(new AddButtonEvent());
        }
      });

      display.getDeleteButton().addClickHandler(new ClickHandler()
      {
        public void onClick(ClickEvent event)
        {
          ArrayList<String> list = display.getSelectedRows();
          deletePerson(list);
        }
      });
    }
    ....
    private void loadDbData()
    {
     ..........
    }
    private void deletePerson(ArrayList<String> ids)
    {
     ..........
     }
   }

编辑:

Presenter是什么,从db加载初始数据,有2个按钮添加和删除。 当按下添加然后加载新表单并且用户能够输入数据并保存到数据库, 删除按钮只是从数据库删除人。

由于

1 个答案:

答案 0 :(得分:5)

单元测试这样一个类的一般想法就像任何其他类一样:

  • 创建依赖项的Mock版本(Display,EventBus等...)
  • 设置对Presenter工作时应该做什么的期望
  • 练习演示者并检查期望

但是,您的Presenter版本存在一些问题:

  • 未显示loadDbData()方法,但我认为这意味着Presenter还可以访问其他一些进行提取的组件。这个组件可以在一个依赖项中被删除,并且嘲笑喜欢其他组件吗?

  • 然后是bind()的测试。 Presenter在此方法中的唯一责任是在人机界面提供的某些按钮上设置回调。你要测试的是:

    • 设置了回调
    • 设置回调执行预期的事情

一些帮助后者的想法:

您可以减少Presenter和Button之间的耦合。如果可能,请从以下位置更改显示界面:

Button getAddButton();

addAddButtonClickedHandler(ClickHandler);

这意味着您的Presenter不必使用返回实际BUtton

的Display对象

您可以将回调内容减少为调用单个方法,然后可以单独测试

protected void bind() {
   display.addAddButtonClickHandler(new ClickHandler() {
       public void onClick(ClickEvent) {
          fireAdded();
       } 
   });
} 

// The fireAdded function can be tested independenty of the Display, potentially with 
// a mock EventBus
protected void fireAdded() {
   event.fireEvent(....)
}

如果你真的想检查回调设置是否正确,那么你可以使用Display类的'Dummy'实现,它提供了所有回调的列表,让你调用它们

private class DummyDisplay implements Display  {

   private List<ClickHandler> addButtonClickHandlers;
   public void addAddButtonClickHandler(ClickHandler handler) {
       addButtonClickHandlers.add(handler);
   }
   public void fireAddButtonClick() {
       for (ClickHandler h in addButtonClickHandlers) {
              h.onClick(new ClickEvent());
       }
   }
   // .... 
}

然后你的测试会:

  • 使用这样的虚拟显示创建演示者
  • 使用bind设置回调
  • 使用display.fireAddButtonClick()模拟用户点击
  • 检查是否有点击结果,可以看到fireAdded的效果

这种类(主要是将其他类粘在一起)往往很难测试;在某些时候,其他类别经过彻底测试,专注于胶粘剂而不是粘合剂会变得有点反作用。

希望这会有所帮助。