`
zhaowanhe
  • 浏览: 2254 次
  • 性别: Icon_minigender_1
  • 来自: 陕西
最近访客 更多访客>>
社区版块
存档分类
最新评论

编写可测试GWT代码的一些小经验

阅读更多

当我们谈及可测试的GWT时总是绕不开MVP模式,一些很经典的帖子里面介绍了使用MVP模式把复杂逻辑控制在Presenter中,将展示相关的逻辑(主要是涉及到GWT native代码的部分)控制在View中。这样就能够使得对主要逻辑代码的测试摆脱GWT-Testcase的束缚,尽情的使用Junit和各种Mock所带来的强力功能。遗憾的是这里有一个完美的假设:假设我们能够把所有native代码控制在View中。而实际开发中我们发现,想做到这一点非常困难。例如我们经常要在Presenter中做一些Alert或者Confirm的工作,又或者我们的一些遗留代码中使用了native方法,特别是这些方法如果使用static方法提供调用的,那简直就是异常噩梦。

把这些代码全都转移到View层中会让Presenter的代码变得支离破碎。对于这类问题我们设计了称之为Barrier的解决方案,顾名思义:Barrier是一种篱笆,在打包运行时他能够把用到了反射、mockGWT无法编译的代码单元隔离出来;在测试阶段,又可以把GWT native代码隔离开。下面是一个针对Window类的Barrier的基本结构:

 

编写可测试GWT代码的一些小经验 - robotz@yeah - IronRobot
 思路很简单,抽象一个接口出来,包含对Window的基本方法调用的封装。使用GWTWindow类实现一个ClientImplBarrier的代码也很简单,就是一个单例方法:

 

 

public static WindowInterface window;

public static WindowInterface getWindow() {         if (window == null)

            window = new WindowObjectBarrierClientImpl();

        return window;

    }

 

So easy 哈,Barrier发挥作用的关键就在这里。我们可以在unit testbefore-class中把HostImpl作为初始值赋值给windw属性。这里的HostImpl我们可以做一个简单实现,把参数打印到控制台上,或者缓存到List里面以备后面进行验证,也可以Mock一个实现出来,统统OK。(HostImpl不要放在和ClientImpl同一个目录的地方,不然GWT编译就通过不了啦)。当然需要为了隔离开而大费周折的类并不多,弄一个BarrierFacade,把常用的类都包装好,维护成本并不大。对代码的侵入性也很小。

遗憾的是,这样做我们就不能保证window属性的隐蔽性了。暂时没有想到好的解决方案。

 

另一种需要我们大费周折隔离的就是RPC调用,GWT.create一下下就可以获得一个远程调用所需要的对象,大神奇。但写单测时怎么办?如果你的Presenter中涉及到需要与服务器交互,disaster。仔细想想,其实就是所谓的RPC总是万变不离其宗的,client端把参数发到server端,server端把结果返回回来。测试时需要网络吗?需要容器吗?当然我们不需要,更不希望需要。所以我们完全可以把网络去掉,把create生成的对象和server端的实现直接绑定在一起。我们可以借助CGlib实现一个create方法达到这个目的。

下面是一个针对同步调用的rpcservicecreate的实现。Impl是一个service的实现。可以直接接上我们具体的servie的实现,不过最好还是用mock对象吧~

 

public static <T> T create(Class<T> rpcInterface, final T impl) {

        Object t = Enhancer.create(Object.class, new Class[] { rpcInterface }, new InvocationHandler() {

             @Override

            public Object invoke(Object self, Method method, Object[] args) throws Throwable {

                String methodName = method.getName();

                Class[] argTypse = method.getParameterTypes();

                Method implMethod = impl.getClass().getMethod(methodName, argTypse);

                if (implMethod == null) {

                    throw new NoSuchMethodError(methodName + " not support in class" +impl.getClass().getName());

                }

                return implMethod.invoke(impl, args);

            }

        });

        return (T) t;

    }

 


 

针对异步调用只要继承一个RequestBuilder并重写send方法就o啦,这里就不贴了

 

通过以上两个方法,我们用junit测试覆盖了大部分的Presenter层的代码,非常好用。

 

当然这还是在一个大前提下:把PresenterView做清晰的划分,这是一把双刃剑。让我们写代码的时候不再那么随心所欲,但同时也能使我们能理清自己的逻辑,写出更漂亮,更整洁的代码。

实现PV的清晰划分并不困难,我们需要明确的是PV的纽带是什么:P响应V触发的事件,V展示P的数据。所以我们是有一些原则来保证接口的明确划分的:

例如:避免V接口的方法声明中包含如getButton之类的方法。

 

另外网上有个老外做的套件叫GWT-test-utils,使用的是javaagent技术,在类加载时对native方法重写,很强大。感谢**同学总是能发现非常好用的工具。

分享到:
评论
1 楼 ccx410 2011-12-19  
安装gwt报错,unable to retrieve osgi.bundle,com.google.gwt.eclipse.sdkbundle如何解决

相关推荐

    gwt-test-utils:gwt-test-utils是一个Java框架,允许以高效,简便的方式测试GWT客户端代码

    编写测试如下所示: @Testpublic void clickOnButtonShouldDisplayMessageInLabel() { // Arrange SampleView view = new SampleView (); // ensure the label is not visible at init assertThat(view . label) . ...

    使用 Cypal Studio for GWT 简化 Ajax 开发

    GWT 应用程序可以在所有主流浏览器中运行,允许与用户进行充分的交互,并且可以在 Java 开发环境内进行全面的测试和调试。 GWT 框架有四个主要组件。一组用 Java 语言实现的部件集合,用于提供所有的标准用户界面 ...

    JAVA上百实例源码以及开源项目源代码

     用JAVA编写了一个小工具,用于检测当前显示器也就是显卡的显示模式,比如分辨率,色彩以及刷新频率等。 Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字  Java波浪文字,一个利用...

    股票买卖最佳时机leetcode-gwtdo:GWTdo是一个.NET库,可帮助开发人员编写可读的测试。它是一种基于Given-When-Th

    库,可帮助开发人员编写可读的测试。 此外,它是一种基于Given-When-Then风格的 DSL,可用于您的测试项目。 入门 写规范 在 C# 方法中使用自然语言指定您的测试。 轻松、简单、快速。 [ Fact ] public void user_...

    JAVA上百实例源码以及开源项目

     用JAVA编写了一个小工具,用于检测当前显示器也就是显卡的显示模式,比如分辨率,色彩以及刷新频率等。 Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字  Java波浪文字,一个利用...

    webfx:JavaFX应用程序编译器。 用JavaFX编写Web应用程序,WebFX将以纯HTML5JS转换它

    通常,GWT只能编译Java代码(您的应用程序逻辑),而不能编译JavaFX代码(您的应用程序UI)。 WebFX通过提供JavaFX的Web端口( 模块)来解决此问题,该端口可以由GWT与您的应用程序代码一起编译。 WebFX还提供了...

    console:HAL管理控制台

    这是一个GWT应用程序-这意味着它几乎完全是用Java编写的。 GWT用于将Java代码转换为一堆JavaScript,HTML和CSS文件。 HAL也使用一些外部JavaScript库。 这些依赖关系使用进行管理,然后使用集成到Maven构建中。 看...

    java开源包8

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包10

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    TrueAutomation.IO Element Picker-crx插件

    使用TrueAutomation.IO智能定位器,可以更快地编写测试并使它们更可靠。 TrueAutomation元素选择器是TrueAutomatio.io生态系统的一部分。 它的创建是为了加快测试的创建速度,并在无法使用ID或任何其他定位符的情况...

    java开源包1

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包11

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包2

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包3

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包6

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包5

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包4

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包7

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

    java开源包9

    GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以...

Global site tag (gtag.js) - Google Analytics