首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Junit:测试用例分离

Junit:测试用例分离
EN

Stack Overflow用户
提问于 2013-10-25 18:57:33
回答 1查看 458关注 0票数 0

这更像是一个junit逻辑问题,而不是任何其他问题。

下面是我的设想:

我有一个独立的java应用程序,它使用来自web服务的数据,并将来自该服务的数据保存在客户机(应用程序正在运行的地方)机器上。

该数据以XML的形式保存,然后由另一个应用程序读取,以便在厚客户端UI上呈现该内容。

下面的图表描述了该流程:

我希望为这个流程编写单元测试,但我无法理解如何对用于使用was服务的逻辑进行单元测试,然后验证在客户端机器上保存的内容是否正确。

另一个难题是如何使用保存在客户机机器上的XML来验证(单元测试) UI上呈现的内容。

我理解每个junit必须尽可能小,并且应该独立地测试底层功能。

应用程序将托管在像Hudson这样的持续集成环境中,可能不会为应用程序提供向该机器写入任何内容的权限。这使问题进一步复杂化。

任何帮助都将不胜感激。

在上面的场景中,为了简单起见,我已经将独立应用程序和厚客户机演示为单独的,但本质上它们可以是一个应用程序。

读取要显示的XML数据的厚客户机是用javafx编写的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-25 19:33:08

您没有指定什么将用作UI?这是一个GUI应用程序还是网络应用?这对一般的方法有一定的影响,但为了给出一些提示,我将分享我的经验。我使用swing做了很多gui应用程序,这将是我的基线。

因此,趋势是使GUI尽可能细,并将只负责显示组件的逻辑放在那里。为此,您可以使用众所周知的设计模式,如表示模型( http://martinfowler.com/eaaDev/PresentationModel.html )或被动视图( http://martinfowler.com/eaaDev/PassiveScreen.html )

然后开始测试业务逻辑。一般准则是:

  • 您不使用外部资源(文件、数据库等)相反,你用假的或者Mock来代替它们,它们为你的测试提供了一些固定的输入。
  • 您只测试类的行为,而不是依赖项的行为。
  • 尽量避免复杂的输入
  • 使用上述模式,您可以模拟您的视图层,并且只测试某些视图方法是否在同步层中调用。

希望我能帮上忙。如果不是的话,让我知道是否有什么东西有点模糊。如果你能给出一个例子,你想如何解决这个问题,以及你对你的方法有什么担忧,那就更好了。

@示例

我没有使用JavaFx的经验,所以我将尝试展示如何在Swing中这样做。这个例子假设你知道什么是模拟,它们是干什么用的。

首先,让我们了解一下瘦客户机中最重要的功能是什么。我会去做类似的事。用户打开xml文件,应用程序以某种形式显示它。(表单并不重要,它可以是树,也可以是表或网格之类的。因为这是我现在不关心的观点)

基本场景是用户选择一个文件,应用程序打开该文件并对其进行分析,然后显示结果。让我们把这个场景称为“开放结果”。

第一次测试:

代码语言:javascript
运行
复制
class OpenResultsShould{
    @Test
    public void loadResults() {
        Data fake = mock (Data.class);
        ViewInterface view = mock(ViewInterface.class); // mocking view
        when(view.getFilename()).thenReturn("file.xml"); // we specify that when getFileName() method of view mock will be called "file.xml" string will be returned.

        ApplicationModelInterface appModel = mock(ApplicationModelInterface.class); // mocking app model
        when(appModel.getDataForView()).thenReturn(fake);

    OpenResultsAction openResults = new OpenResultsAction( view, appModel );

        openResults.actionPerformed(new ActionEvent());

        verify(view).getFileName();           // checks that view.getFileName was called within actionPerdormed()
        verify(appModel).load("file.xml");    // check that appModel.load( ) with file.xml as parameter was called within actionPerformed()
        verify(appModel).getDataForView();    // similar to above
        verify(view).loadDataFromModel( fake ); // finally I check if loadDataFromModel on view was called.
    }
}

这个测试的目的是检查OpenResultsAction是否会完成这项工作。这里我们没有测试所解析的内容以及gui是否有正确的数据。我们测试某些对象上的某些方法是否被调用。此测试还指定了操作类、视图和applicationModel之间的约定。这是通过接口完成的。因此,您以后可以提供具体的实现,并在下一步进行测试。然后,我将提供实现,我将跳过,以使这个例子尽可能短。

接下来是什么。由于gui根本不需要测试,所以我会进行ApplicationModel测试。在第一个测试中,我们指定applicationModelInterface应该有方法加载(字符串文件名);我们将测试它的具体实现。

代码语言:javascript
运行
复制
class ApplicationModelShould{
    @Test
    public void loadModelFromFile() {
        XMLDocument xml = new XMLDocumentFake();
        XMLFileLoader xFileLoader = mock(XMLFileLoader.class);
        when(xFileLoader.load("file.xml").thenReturn( xml );
        ApplicationModelInterface appModel = new ConcreteApplicationModel( new FileLoaderFake() );

        appModel.load("plik.xml"); // it should call xFileLoader and then parse returned xml document.
        doReturn(xml).when(xFileLoader).load("plik.xml"); // verifies if xFileLoader returned xml when appModel.load called it's load method. 
       Data expectedResult = populateExpectedResults();
       assertEquals( appModel.getDataForView().equals( expectedResult ) );
    }
}

XMLDocument是什么?它存储xml文件的内容。它可以表示为文件行的向量。我们的AppModelLoader将把它解析为对象。XFileLoader是另一层,它允许我在单元测试中摆脱文件操作。在这里,它是被嘲笑的,但是在实际的应用程序中,它应该被替换为一些将在xml文件中读取并返回XMLDocument的东西。data是一个用于存储解析数据的类。如果xml的内容是"Tom34“,那么数据将如下所示:

代码语言:javascript
运行
复制
class Data{
    private Person person;
    Data(Person person){ this.person = person; }
    ...
};

class Person{
    private String name;
    private int age;
    .... setters, getters and constructors
}

基本上就是这样。当然,还需要进行更多的测试,例如,如果view.getFileName()将在OpenResultsAction (用户点击JFileChooser上单击cancel )中返回空字符串,那么我需要验证是否没有调用任何其他字符串。如果我要测试所有的类,那么我将编写GUI部分并将其组合起来。

如果这有意义的话请告诉我。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19597489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档