NoSQLUnit 0.3.0发布

介绍

单元测试是一种验证应用程序中可测试的最小部分的方法。 单元测试必须遵循FIRST规则; 这些是快速,隔离,可重复,自我验证和及时的。
考虑到没有持久层(典型的关系数据库或新的NoSQL数据库)的JEE应用程序很奇怪,因此编写持久层的单元测试也应该很有趣。 当我们编写持久层的单元测试时,我们应该专注于不破坏FIRST规则的两个主要概念,即快速规则和隔离规则。

如果他们不访问网络或文件系统,则我们的测试将很快,并且在持久性系统的情况下,网络和文件系统是最常用的资源。 对于RDBMS (SQL),存在许多Java内存数据库,例如Apache DerbyH2HSQLDB 。 顾名思义,这些数据库已嵌入到您的程序中,并且数据存储在内存中,因此您的测试仍然很快。 问题在于NoSQL系统,因为它们具有异质性。 一些系统使用Document方法(例如MongoDb ),其他Column(例如Hbase )或Graph(例如Neo4J )工作。 因此,供应商应提供内存模式,没有通用的解决方案。

我们的测试必须与自己隔离。 一种测试方法修改另一种测试方法的结果是不可接受的。 在持久性测试的情况下,当前一个测试方法向数据库插入一个条目,而下一个测试方法执行找到更改时,就会发生这种情况。 因此,在执行每个测试之前,应该以已知状态找到数据库。 请注意,如果您的测试发现数据库处于已知状态,则测试将是可重复的,如果测试断言取决于先前的测试执行,则每个执行都是唯一的。 对于RDBMS之类的同类系统,存在DBUnit来在每次执行之前将数据库保持在已知状态。 但是还没有用于异构NoSQL系统的DBUnit框架。

NoSQLUnit通过提供一个JUnit扩展来解决此问题,该扩展可以帮助我们管理NoSQL系统的生命周期,并有助于将数据库维护为已知状态。

NoSQLUnit

NoSQLUnit是一个JUnit扩展,它使使用NoSQL后端的系统的编写单元测试和集成测试更加容易,它由两组规则和一组注释组成。
第一组规则是负责管理数据库生命周期的规则 ; 每个受支持的后端都有两个。

  • 第一个(如果可能的话)它是内存模式。 此模式负责以“内存中”模式启动和停止数据库系统。 此模式通常在单元测试执行期间使用。
  • 第二个是托管模式。 此模式负责启动NoSQL服务器,但作为远程进程(在本地计算机中)并停止它。 通常在集成测试执行期间使用。

第二组规则是负责将数据库保持为已知状态的规则 。 每个受支持的后端都有自己的后端,可以理解为与已定义数据库的连接,该数据库将用于执行所需的操作以维护系统的稳定性。

请注意,由于NoSQL数据库是异构数据库,因此每个系统都需要自己的实现。
最后提供了两个注释, @UsingDataSet@ShouldMatchDataSet (非常感谢Arquillian的名字),用于指定数据集和预期数据集的位置。

MongoDb示例

现在,我将解释一个非常简单的示例,说明如何使用NoSQLUnit,要全面了解所提供的所有功能,请阅读链接中的文档或以pdf格式下载
要使用MongoDB的使用NoSQLUnit你只需要添加下一依赖性:

<dependency>
  <groupId>com.lordofthejars<groupId>
  <artifactId>nosqlunit-mongodb<artifactId>
  <version>0.3.0<version>
 <dependency>

第一步是定义测试所需的生命周期管理策略。 根据您要实施的测试类型(单元测试,集成测试,部署测试等),您将需要内存方式, 托管方式或远程方式。

对于此示例,我们将使用通过ManagedMongoDb规则使用托管方法),但请注意,还支持内存中 MongoDb管理(请参见文档说明)。

下一步是配置Mongodb规则, 规则负责通过插入和删除定义的数据集来将MongoDb数据库保持在已知状态。 您必须注册MongoDbRule JUnit规则类,该类需要一个配置参数,其中包含主机,端口或数据库名称之类的信息。

为了简化开发人员的生活并使代码更易读,可以使用流畅的界面来创建这些配置对象。

让我们看一下代码:

首先是一个简单的POJO类,它将用作模型类:

public class Book {
 
  private String title;
 
  private int numberOfPages;
 
  public Book(String title, int numberOfPages) {
   super();
   this.title = title;
   this.numberOfPages = numberOfPages;
  }
 
  public void setTitle(String title) {
   this.title = title;
  }
 
  public void setNumberOfPages(int numberOfPages) {
   this.numberOfPages = numberOfPages;
  }
 
 
  public String getTitle() {
   return title;
  }
 
  public int getNumberOfPages() {
   return numberOfPages;
  }
 }

下一业务类负责管理对MongoDb服务器的访问:

public class BookManager {
 
  private static final Logger LOGGER = LoggerFactory.getLogger(BookManager.class);
 
  private static final MongoDbBookConverter MONGO_DB_BOOK_CONVERTER = new MongoDbBookConverter();
  private static final DbObjectBookConverter DB_OBJECT_BOOK_CONVERTER = new DbObjectBookConverter();
 
 
  private DBCollection booksCollection;
 
  public BookManager(DBCollection booksCollection) {
   this.booksCollection = booksCollection;
  }
 
  public void create(Book book) {
   DBObject dbObject = MONGO_DB_BOOK_CONVERTER.convert(book);
   booksCollection.insert(dbObject);
  }
 }

现在该进行测试了。 在下一个测试中,我们将验证一本书是否已正确插入数据库。

package com.lordofthejars.nosqlunit.demo.mongodb;
 
 public class WhenANewBookIsCreated {
 
  @ClassRule
  public static ManagedMongoDb managedMongoDb = newManagedMongoDbRule().mongodPath('optmongo').build();
 
  @Rule
  public MongoDbRule remoteMongoDbRule = new MongoDbRule(mongoDb().databaseName('test').build());
 
  @Test
  @UsingDataSet(locations='initialData.json', loadStrategy=LoadStrategyEnum.CLEAN_INSERT)
  @ShouldMatchDataSet(location='expectedData.json')
  public void book_should_be_inserted_into_repository() {
 
   BookManager bookManager = new BookManager(MongoDbUtil.getCollection(Book.class.getSimpleName()));
 
   Book book = new Book('The Lord Of The Rings', 1299);
   bookManager.create(book);
  }
 
 }

看到首先,我们正在使用ClassRule注释创建与MongoDb服务器的托管连接。 在这种情况下,我们将以编程方式配置MongoDb路径,但也可以从MONGO_HOME环境变量进行设置。 请参见此处所有可用参数的完整说明。

加载测试时将执行此规则 ,并将启动MongoDb实例。 执行完所有测试后,还将关闭服务器。

Next Rule在任何测试方法之前执行,负责将数据库保持在已知状态。 注意,我们仅配置工作数据库,在本例中为测试数据库。

最后,我们用@UsingDataSet注释方法测试,指示执行每个测试之前要在哪里找到要插入的数据,并@ShouldMatchDataSet定位预期的数据集。

{
  'Book':
  [
   {'title':'The Hobbit','numberOfPages':293}
  ]
 }
{
  'Book':
  [
   {'title':'The Hobbit','numberOfPages':293},
   {'title':'The Lord Of The Rings','numberOfPages':1299}
  ]
 }

我们正在设置文件initialData.json初始数据集位于classpath中COM / lordofthejars / nosqlunit /演示/ MongoDB的/ initialData.json和预期的数据集叫expectedData.json。

最后说明

虽然NoSQLUnit是在早期阶段,MongoDB中的部分几乎已经完成,在接下来的版本中的新功能,当然还有新的数据库将得到支持。 下一个NoSQL支持的引擎将是Neo4JCassandraHBaseCouchDb

另请阅读文档 ,您将在此处找到对每个功能的完整说明。

最后,您的任何建议,任何建议或任何建议都将受到欢迎。

保持学习!

完整代码

参考: NoSQLUnit 0.3.0从我们的JCG合作伙伴 Alex Soto在“ 一个罐子统治所有”博客上发布。


翻译自: https://www.javacodegeeks.com/2012/06/nosqlunit-030-released.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值