使用MongoDB进行unit testing

我select的数据库是MongoDB。 我正在编写一个数据层API来从客户端应用程序中抽象实现细节 – 也就是说,我基本上提供了一个单独的公共接口(一个充当IDL的对象)。

我正在testing我的逻辑,因为我以TDD方式进行testing。 在每个unit testing之前,调用@Before方法来创build数据库单例,在此之后,当testing完成时,将调用@After方法来删除数据库。 这有助于提高unit testing的独立性。

几乎所有的unit testing,即执行上下文查询 ,都需要某种插入逻辑才能发生。 我的公共接口提供了一个插入方法 – 但是,使用这种方法作为每个unit testing的前驱逻辑似乎是不正确的。

真的,我需要一些嘲弄的机制,但是我还没有太多的嘲讽框架的经验,似乎Google没有返回一个可以用于MongoDB的嘲笑框架。

别人在这些情况下做什么? 也就是说,人们如何testing与数据库交互的代码呢?

此外,我的公共接口连接到一个外部configuration文件中定义的数据库 – 这似乎是不正确的使用这个连接,我的unit testing – 再次,这种情况,将受益于某种嘲笑?

从技术上讲,与数据库(nosql或其他)交谈的testing不是unit testing ,因为testing正在testing与外部系统的交互,而不仅仅是testing一个单独的代码单元。 然而,与数据库交谈的testing通常是非常有用的,并且通常足够快以便与其他unit testing一起运行。

通常我有一个服务接口(例如UserService),它封装了处理数据库的所有逻辑。 依赖于UserService的代码可以使用UserService的模拟版本,并且很容易testing。

当testing与Mongo交谈的服务(例如MongoUserService)的实现时,最简单的方法是编写一些在本地机器上启动/停止mongo进程的java代码,然后让MongoUserService连接到它, 笔记 。

在testingMongoUserService的时候,你可以尝试模拟数据库的function,但通常这太容易出错,而且不会testing你真正想要testing的东西,这是与真实数据库的交互。 所以在为MongoUserService编写testing时,需要为每个testing设置一个数据库状态。 在DbUnit中查看一个用数据库这样做的框架的例子。

正如Sbridges在这篇文章中写道的,不要有一个专门的服务(有时也称为存储库或DAO),它从逻辑中抽象出数据访问。 然后你可以通过提供一个DAO的模拟来testing逻辑。

我所做的另一个方法是创build一个蒙古对象的模拟(例如PowerMockito),然后返回适当的结果。 这是因为您不必testing数据库是否在unit testing中工作,但是您应该testing是否将正确的查询发送到数据库。

 Mongo mongo = PowerMockito.mock(Mongo.class); DB db = PowerMockito.mock(DB.class); DBCollection dbCollection = PowerMockito.mock(DBCollection.class); PowerMockito.when(mongo.getDB("foo")).thenReturn(db); PowerMockito.when(db.getCollection("bar")).thenReturn(dbCollection); MyService svc = new MyService(mongo); // Use some kind of dependency injection svc.getObjectById(1); PowerMockito.verify(dbCollection).findOne(new BasicDBObject("_id", 1)); 

这也是一个select。 当然,创build模拟和返回适当的对象只是上面的一个例子。

我在Java中编写了一个MongoDB存根实现: mongo-java-server

默认是内存后端,可以在unit testing和集成testing中轻松使用。

 MongoServer server = new MongoServer(new MemoryBackend()); // bind on a random local port InetSocketAddress serverAddress = server.bind(); MongoClient client = new MongoClient(new ServerAddress(serverAddress)); DBCollection coll = client.getDB("testdb").getCollection("testcoll"); // creates the database and collection in memory and inserts the object coll.insert(new BasicDBObject("key", "value")); assertEquals(1, collection.count()); assertEquals("value", collection.findOne().get("key")); client.close(); server.shutdownNow(); 
Interesting Posts