草庐IT

java - 我们如何为涉及与数据库连接的方法编写单元测试?

coder 2024-03-30 原文

我一直有一个关于为实际与数据库通信并返回一些值的网络方法编写单元测试的查询。

例如,我有一个名为“StudentInfoService”的 Web 服务。 该网络服务提供了一个 API“getStudentInfo(studentid)”

这是一些示例片段

public class StudentInfoService
{
    public StudentInfo getStudentInfo(long studentId) {
            //Communicates with DB and creates
            // StudentInfo object with necessary information
            // and returns it to the caller.
    }
}

我们实际上如何为这个方法 getStudentInfo 编写单元测试? 通常,我们如何为涉及资源(数据库、文件、JNDI 等)连接的方法编写单元测试?

最佳答案

首先,您示例中的类 StudentInfoService 不可测试,或者至少不容易测试。这是出于一个非常简单的原因 - 无法将数据库连接对象传递给类,至少不能在您列出的方法中传递。

要使类可测试,您需要按以下方式构建您的类:

public class StudentInfoService
{
    private Connection conn;

    public StudentInfoService(Connection conn)
    {
        this.conn = conn;
    }

    public StudentInfo getStudentInfo(long studentId) {
            //Uses the conn object to communicate with DB and creates
            // StudentInfo object with necessary information
            // and returns it to the caller.
    }
}

以上代码允许通过构造函数进行依赖注入(inject)。如果更合适的话,您可以使用 setter 注入(inject)而不是构造函数注入(inject),但它通常不适用于 DAO/Repository 类,因为该类不能被认为是完全形成的,没有连接。

依赖注入(inject)将允许您的测试用例创建到数据库的连接(它是被测类/系统的协作者),而不是让类/系统本身创建协作者对象。简而言之,您正在将建立数据库连接的机制与您的类分离。如果您的类之前查找 JNDI 数据源然后创建连接,那么它将无法测试,除非您使用 Apache Cactus 将其部署到容器中。或类似的框架 Arquillian ,或者如果您使用了嵌入式容器。通过将创建连接的问题与类隔离开来,您现在可以自由地在类外部的单元测试中创建连接,并根据需要将它们提供给类,从而允许您在 Java SE 环境中运行测试。

这将使您能够使用面向数据库的单元测试框架,例如 DbUnit ,这将允许您在每次测试之前将数据库设置为已知状态,然后将连接传递给 StudentInfoService 类,然后断言该类的状态(以及协作者,即数据库)测试后。

必须强调的是,当您对类进行单元测试时,您的类必须是唯一被测试的系统。像连接和数据源这样的项目仅仅是可以并且应该被 mock 的合作者。一些单元测试会使用内存数据库,如 H2 , HSQL , 或 Derby用于单元测试,并使用数据库的生产等效安装进行集成和功能测试。

关于java - 我们如何为涉及与数据库连接的方法编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6723711/

有关java - 我们如何为涉及与数据库连接的方法编写单元测试?的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  3. ruby - 如何为 emacs 安装 ruby​​-mode - 2

    我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby​​提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  6. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐