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

adg*_*gfs 9 java mvp gwt unit-testing

我有一个简单的应用程序,并希望使其可测试.我是这个领域的新人.这是一个简单的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)
    {
     ..........
     }
   }
Run Code Online (Sandbox Code Playgroud)

编辑:

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

谢谢

pht*_*ier 5

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

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

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

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

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

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

一些帮助后者的想法:

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

Button getAddButton();
Run Code Online (Sandbox Code Playgroud)

addAddButtonClickedHandler(ClickHandler);
Run Code Online (Sandbox Code Playgroud)

这意味着您的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(....)
}
Run Code Online (Sandbox Code Playgroud)

如果你真的想要检查回调是否正确设置,那么你可以使用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());
       }
   }
   // .... 
}
Run Code Online (Sandbox Code Playgroud)

然后你的测试会:

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

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

希望这会有所帮助.