{"id":16689406,"url":"https://github.com/lordofthejars/nosql-unit","last_synced_at":"2025-05-16T18:07:15.726Z","repository":{"id":3297067,"uuid":"4338484","full_name":"lordofthejars/nosql-unit","owner":"lordofthejars","description":"NoSQL Unit is a JUnit extension that helps you write NoSQL unit tests.","archived":false,"fork":false,"pushed_at":"2022-12-14T20:32:52.000Z","size":1983,"stargazers_count":383,"open_issues_count":51,"forks_count":121,"subscribers_count":34,"default_branch":"master","last_synced_at":"2025-04-12T16:58:35.697Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lordofthejars.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-05-15T17:25:43.000Z","updated_at":"2024-10-10T17:39:29.000Z","dependencies_parsed_at":"2023-01-13T12:24:35.642Z","dependency_job_id":null,"html_url":"https://github.com/lordofthejars/nosql-unit","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lordofthejars%2Fnosql-unit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lordofthejars%2Fnosql-unit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lordofthejars%2Fnosql-unit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lordofthejars%2Fnosql-unit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lordofthejars","download_url":"https://codeload.github.com/lordofthejars/nosql-unit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254582907,"owners_count":22095518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T15:48:09.063Z","updated_at":"2025-05-16T18:07:15.702Z","avatar_url":"https://github.com/lordofthejars.png","language":"Java","funding_links":[],"categories":["测试"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/tinesoft/nosql-unit.svg?branch=master)](https://travis-ci.org/lordofthejars/nosql-unit)\n\nDocumentation\n=============\n\nNoSQLUnit Core\n==============\n\nOverview\n--------\n\nUnit testing is a method by which the smallest testable part of an\napplication is validated. Unit tests must follow the FIRST Rules; these\nare Fast, Isolated, Repeatable, Self-Validated and Timely.\n\nIt is strange to think about a JEE application without persistence layer\n(typical Relational databases or new *NoSQL* databases) so should be\ninteresting to write unit tests of persistence layer too. When we are\nwriting unit tests of persistence layer we should focus on to not break\ntwo main concepts of FIRST rules, the fast and the isolated ones.\n\nOur tests will be *fast* if they don't access network nor filesystem,\nand in case of persistence systems network and filesystem are the most\nused resources. In case of RDBMS ( *SQL* ), many Java in-memory\ndatabases exist like Apache Derby , H2 or HSQLDB . These databases, as\ntheir name suggests are embedded into your program and data are stored\nin memory, so your tests are still fast. The problem is with *NoSQL*\nsystems, because of their heterogeneity. Some systems work using\nDocument approach (like MongoDb ), other ones Column (like Hbase ), or\nGraph (like Neo4J ). For this reason the in-memory mode should be\nprovided by the vendor, there is no a generic solution.\n\nOur tests must be isolated from themselves. It is not acceptable that\none test method modifies the result of another test method. In case of\npersistence tests this scenario occurs when previous test method insert\nan entry to database and next test method execution finds the change. So\nbefore execution of each test, database should be found in a known\nstate. Note that if your test found database in a known state, test will\nbe repeatable, if test assertion depends on previous test execution,\neach execution will be unique. For homogeneous systems like RDBMS ,\n*DBUnit* exists to maintain database in a known state before each\nexecution. But there is no like *DBUnit* framework for heterogeneous\n*NoSQL* systems.\n\n*NoSQLUnit* resolves this problem by providing a *JUnit* extension which\nhelps us to manage lifecycle of NoSQL systems and also take care of\nmaintaining databases into known state.\n\nRequirements\n------------\n\nTo run *NoSQLUnit* , *JUnit 4.10* or later must be provided. This is\nbecause of *NoSQLUnit* is using *Rules* , and they have changed from\nprevious versions to 4.10.\n\nAlthough it should work with JDK 5 , jars are compiled using JDK 6 .\n\nNoSQLUnit\n---------\n\n*NoSQLUnit* is a *JUnit* extension to make writing unit and integration\ntests of systems that use NoSQL backend easier and is composed by two\nsets of *Rules* and a group of annotations.\n\nFirst set of *Rules* are those responsible of managing database\nlifecycle; there are two for each supported backend.\n\n-   The first one (in case it is possible) it is the *in-memory* mode.\n    This mode takes care of starting and stopping database system in \"\n    *in-memory* \" mode. This mode will be typically used during unit\n    testing execution.\n\n-   The second one is the *managed* mode. This mode is in charge of\n    starting *NoSQL* server but as remote process (in local machine) and\n    stopping it. This will typically used during integration testing\n    execution.\n\nYou can add them in Test Suites and/or Tests Classes, *NoSQLUnit* takes care of only starting database once.\n\nSecond set of *Rules* are those responsible of maintaining database into\nknown state. Each supported backend will have its own, and can be\nunderstood as a connection to defined database which will be used to\nexecute the required operations for maintaining the stability of the\nsystem.\n\nNote that because *NoSQL* databases are heterogeneous, each system will\nrequire its own implementation.\n\nAnd finally two annotations are provided,\n[@UsingDataSet](#seeding_database) and\n[@ShouldMatchDataSet](#verifying_database) , (thank you so much\n*Arquillian* people for the name).\n\n### Seeding Database\n\n@UsingDataSet is used to seed database with defined data set. In brief\ndata sets are files that contain all data to be inserted to configured\ndatabase. In order to seed your database, use *@UsingDataSet*\nannotation, you can define it either on the test itself or on the class\nlevel. If there is definition on both, test level annotation takes\nprecedence. This annotation has two attributes locations and\nloadStrategy .\n\nWith locations attribute you can specify *classpath* datasets location.\nLocations are relative to test class location. Note that more than one\ndataset can be specified.\n\nAlso withSelectiveLocations attribute can be used to specify datasets location. See Advanced Usage chapter for more information.\n\nIf files are not specified explicitly, next\nstrategy is applied:\n\n-   First searches for a file on classpath in same package of test class\n    with next file name, `[test class name]#[test method\n                                name].[format]\n                            ` (only if annotation is present at test\n    method).\n\n-   If first rule is not met or annotation is defined at class scope,\n    next file is searched on classpath in same package of test class,\n    `[test class name].[default format]` .\n\n\u003e **Warning**\n\u003e\n\u003e datasets must reside into *classpath* and format depends on *NoSQL*\n\u003e vendor.\n\nSecond attribute provides strategies for inserting data. Implemented\nstrategies are:\n\n  --------------- ----------------------------------------------------------------------------------------------------------------------------------------\n  INSERT          Insert defined datasets before executing any test method.\n  DELETE\\_ALL     Deletes all elements of database before executing any test method.\n  CLEAN\\_INSERT   This is the most used strategy. It deletes all elements of database and then insert defined datasets before executing any test method.\n  --------------- ----------------------------------------------------------------------------------------------------------------------------------------\n\n  : Load Strategies\n\nAn example of usage:\n\n~~~~ {.java}\n@UsingDataSet(locations=\"my_data_set.json\", loadStrategy=LoadStrategyEnum.INSERT)\n~~~~\n\n### Verifying Database\n\nSometimes it might imply a huge amount of work asserting database state\ndirectly from testing code. By using *@ShouldMatchDataSet* on test\nmethod, *NoSQLUnit* will check if database contains expected entries\nafter test execution. As with *@ShouldMatchDataSet* annotation you can\ndefine classpath file location, or using withSelectiveMatche, see Advanced Usage chapter for more information.\nIf it is not dataset supplied next convention is used:\n\n-   First searches for a file on classpath in same package of test class\n    with next file name, `[test class name]#[test method\n                                name]-expected.[format]\n                            ` (only if annotation is present at test\n    method).\n\n-   If first rule is not met or annotation is defined at class scope,\n    file is searched on classpath in same package of test class,\n    `[test class name]-expected.[default format]` .\n\n\u003e **Warning**\n\u003e\n\u003e datasets must reside into *classpath* and format depends on *NoSQL*\n\u003e vendor.\n\nAn example of usage:\n\n~~~~ {.java}\n@ShouldMatchDataSet(location=\"my_expected_data_set.json\")\n~~~~\n\nMongoDB Engine\n==============\n\nMongoDB\n=======\n\nMongoDB is a *NoSQL* database that stores structured data as *JSON-like*\ndocuments with dynamic schemas.\n\n**NoSQLUnit** supports *MongoDB* by using next classes:\n\n  ----------- -----------------------------------------------------\n  In Memory   com.lordofthejars.nosqlunit.mongodb.InMemoryMongoDb\n  Managed     com.lordofthejars.nosqlunit.mongodb.ManagedMongoDb\n  ----------- -----------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- -------------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.mongodb.MongoDbRule\n  ---------------------- -------------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use **NoSQLUnit** with MongoDb you only need to add next dependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-mongodb\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nNote that if you are plannig to use **in-memory** approach it is implemented using\n*Fongo* . *Fongo* is a new project that help with unit testing\nJava-based MongoDb Applications. [Fongo](https://github.com/fakemongo/fongo)\n\nDataset Format\n--------------\n\nDefault dataset file format in *MongoDB* module is *json* .\n\nDatasets must have next [format](#ex.mongodb_dataset) :\n\n~~~~ {.json}\n{\n    \"name_collection1\": [\n    {\n        \"attribute_1\":\"value1\",\n        \"attribute_2\":\"value2\"\n    },\n    {\n        \"attribute_3\":2,\n        \"attribute_4\":\"value4\"\n    }\n    ],\n    \"name_collection2\": [\n        ...\n    ],\n    ....\n}\n~~~~\n\nNotice that if attributes value are integers, double quotes are not\nrequired.\n\n\u003e If you want to use ISODate function or any other javascript function you should see how *MongoDB* Java Driver deals with it. For example in case of ISODate:\n\n~~~~ {.json}\n\"bornAt\":{ \"$date\" : \"2011-01-05T10:09:15.210Z\"}\n~~~~\n\nWith last versions of **MongoDB**, index support is also implemented allowing developers to define indexes through defined document properties. For more information visit [MongoDB](http://docs.mongodb.org/manual/core/indexes/). In this case dataset has been changed to let us define indexes too.\n\n~~~~ {.json}\n{\n   \"collection1\":{\n      \"indexes\":[\n         {\n            \"index\":{\n               \"code\":1\n            }\n         }\n      ],\n      \"data\":[\n         {\n            \"id\":1,\n            \"code\":\"JSON dataset\"\n         },\n         {\n            \"id\":2,\n            \"code\":\"Another row\"\n         }\n      ]\n   }\n}\n~~~~\n\nNote that we define the collection name, and then we define two subdocuments. The first one is where we define an array of indexes, all of them related to defined collection and we define which fields are going to be indexed (same as document as defined in **MongoDB** index specification). And then data property, where we define all documents that goes into collection under test.\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\n**in-memory** approach, **managed** approach or **remote** approach.\n\nTo configure **in-memory** approach you should only instantiate next\n[rule](#program.inmemory_conf) :\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.InMemoryMongoDb.InMemoryMongoRuleBuilder.newInMemoryMongoDbRule;\n\n@ClassRule\npublic static InMemoryMongoDb inMemoryMongoDb = newInMemoryMongoDbRule().build();\n~~~~\n\nTo configure the **managed** way, you should use ManagedMongoDb rule and\nmay require some [configuration](#program.managed_conf) parameters.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.ManagedMongoDb.MongoServerRuleBuilder.newManagedMongoDbRule;\n\n@ClassRule\npublic static ManagedMongoDb managedMongoDb = newManagedMongoDbRule().build();\n~~~~\n\nBy default managed *MongoDB* rule uses next default values:\n\n-   *MongoDB* installation directory is retrieved from `MONGO_HOME`\n    system environment variable.\n\n-   Target path, that is the directory where *MongoDb* server is\n    started, is `target/mongo-temp` .\n\n-   Database path is at `{target\n                                    path}\n                                ` `/mongo-dbpath` .\n\n-   Because after execution of tests all generated data is removed, in\n    `{target\n                                    path}\n                                ` `/logpath` will remain log file\n    generated by the server.\n\n-   In *Windows* systems executable should be found as `bin/mongod.exe`\n    meanwhile in *MAC OS* and *\\*nix* should be found as `bin/mongod` .\n\n-   No journaling.\n\nManagedMongoDb can be created from scratch, but for making life easier,\na *DSL* is provided using MongoServerRuleBuilder class. For\n[example](#program.managed_specific_conf) :\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.ManagedMongoDb.MongoServerRuleBuilder.newManagedMongoDbRule;\n\n@ClassRule\npublic static ManagedMongoDb managedMongoDb =\nnewManagedMongoDbRule().mongodPath(\"/opt/mongo\").appendSingleCommandLineArguments(\"-vvv\").build();\n~~~~\n\nIn [example](#program.managed_specific_conf) we are overriding\n`MONGO_HOME` variable (in case has been set) and set mongo home at\n`/opt/mongo` . Moreover we are appending a single argument to *MongoDB*\nexecutable, in this case setting log level to number 3 (-vvv). Also you\ncan append *property=value* arguments using\n`appendCommandLineArguments(String argumentName, String\n                        argumentValue)\n                    ` method.\n\n\u003e **Warning**\n\u003e\n\u003e when you are specifying command line arguments, remember to add slash\n\u003e (-) and double slash (--) where is necessary.\n\nTo stop *MongoDB* instance, **NoSQLUnit** sends a `shutdown` command to\nserver using *Java Mongo API*.\n\nConfiguring **remote** approach does not require any special rule\nbecause you (or System like Maven ) is the responsible of starting and\nstopping the server. This mode is used in deployment tests where you are\ntesting your application on real environment.\n\n### Configuring MongoDB Connection\n\nNext step is configuring ***MongoDB*** rule in charge of maintaining\n*MongoDB* database into known state by inserting and deleting defined\ndatasets. You must register MongoDbRule *JUnit* rule class, which\nrequires a configuration parameter with information like host, port or\ndatabase name.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects. Two\ndifferent kind of configuration builders exist.\n\nThe first one is for configuring a connection to in-memory *Fongo*\nserver. For almost all cases default parameters are enough.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.MongoDbRule.MongoDbRuleBuilder.newMongoDbRule;\n\n@Rule\npublic MongoDbRule embeddedMongoDbRule = newMongoDbRule().defaultEmbeddedMongoDb(\"test\");\n~~~~\n\nThe second one is for configuring a connection to managed/remote *MongoDB*\nserver. Default values are:\n\n  ---------------- -------------------------------\n  Host             localhost\n  Port             27017\n  Authentication   No authentication parameters.\n  ---------------- -------------------------------\n\n  : Default Managed Configuration Values\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.MongoDbConfigurationBuilder.mongoDb;\n\n@Rule\npublic MongoDbRule remoteMongoDbRule = new MongoDbRule(mongoDb().databaseName(\"test\").build());\n~~~~\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.MongoDbConfigurationBuilder.mongoDb;\n\n@Rule\npublic MongoDbRule remoteMongoDbRule = new MongoDbRule(mongoDb().databaseName(\"test\").host(\"my_remote_host\").build());\n~~~~\n\nBut also we can define it to use Spring Data MongoDB defined instance.\n\nIf you are plannig to use **Spring Data MongoDB**, you may require to use the *Mongo* instance defined within Spring Application Context, mostly because you are defining an embedded connection using **Fongo**:\n\n~~~~ {.xml}\n\u003cbean name=\"fongo\" class=\"com.github.fakemongo.Fongo\"\u003e\n    \u003cconstructor-arg value=\"InMemoryMongo\" /\u003e\n\u003c/bean\u003e\n\u003cbean id=\"mongo\" factory-bean=\"fongo\" factory-method=\"getMongo\" /\u003e\n~~~~\n\nIn these cases you should use an special method which gets *Mongo* **Fongo** instance, instead of creating new one.\n\n~~~~ {.java}\n@Autowired\nprivate ApplicationContext applicationContext;\n\n@Rule\npublic MongoDbRule mongoDbRule = newMongoDbRule().defaultSpringMongoDb(\"test\");\n~~~~\n\n\u003e Note that you need to autowire the application context, so **NoSQLUnit** can inject instance defined within application context into *MongoDbRule*.\n\n### Complete Example\n\nConsider a library application, which apart from multiple operations, it\nallow us to add new books to system. Our [model](#example.book_model) is\nas simple as:\n\n~~~~ {.java}\npublic class Book {\n\n    private String title;\n\n    private int numberOfPages;\n\n    public Book(String title, int numberOfPages) {\n        super();\n        this.title = title;\n        this.numberOfPages = numberOfPages;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public void setNumberOfPages(int numberOfPages) {\n        this.numberOfPages = numberOfPages;\n    }\n\n\n    public String getTitle() {\n        return title;\n    }\n\n    public int getNumberOfPages() {\n        return numberOfPages;\n    }\n}\n~~~~\n\nNext business [class](#example.book_manager) is the responsible of\nmanaging access to *MongoDb* server:\n\n~~~~ {.java}\npublic class BookManager {\n\n    private static final Logger LOGGER = LoggerFactory.getLogger(BookManager.class);\n\n    private static final MongoDbBookConverter MONGO_DB_BOOK_CONVERTER = new MongoDbBookConverter();\n    private static final DbObjectBookConverter DB_OBJECT_BOOK_CONVERTER = new DbObjectBookConverter();\n\n\n    private DBCollection booksCollection;\n\n    public BookManager(DBCollection booksCollection) {\n        this.booksCollection = booksCollection;\n    }\n\n    public void create(Book book) {\n        DBObject dbObject = MONGO_DB_BOOK_CONVERTER.convert(book);\n        booksCollection.insert(dbObject);\n    }\n}\n~~~~\n\nAnd now it is time for testing. In next\n[test](#example.test_insert_book) we are going to validate that a book\nis inserted correctly into database.\n\n~~~~ {.java}\npackage com.lordofthejars.nosqlunit.demo.mongodb;\n\npublic class WhenANewBookIsCreated {\n\n    @ClassRule\n    public static ManagedMongoDb managedMongoDb = newManagedMongoDbRule().mongodPath(\"/opt/mongo\").build();\n\n    @Rule\n    public MongoDbRule remoteMongoDbRule = new MongoDbRule(mongoDb().databaseName(\"test\").build());\n\n    @Test\n    @UsingDataSet(locations=\"initialData.json\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    @ShouldMatchDataSet(location=\"expectedData.json\")\n    public void book_should_be_inserted_into_repository() {\n\n        BookManager bookManager = new BookManager(MongoDbUtil.getCollection(Book.class.getSimpleName()));\n\n        Book book = new Book(\"The Lord Of The Rings\", 1299);\n        bookManager.create(book);\n    }\n\n}\n~~~~\n\nIn [previous](#example.test_insert_book) test we have defined that\n*MongoDB* will be managed by test by starting an instance of server\nlocated at `/opt/mongo` . Moreover we are setting an\n[initial](#example.dataset_book) dataset in file `initialData.json`\nlocated at classpath\n`com/lordofthejars/nosqlunit/demo/mongodb/initialData.json\n                    ` and [expected](#example.expected_dataset_book)\ndataset called `expectedData.json` .\n\n~~~~ {.json}\n{\n    \"Book\":\n    [\n        {\"title\":\"The Hobbit\",\"numberOfPages\":293}\n    ]\n}\n~~~~\n\n~~~~ {.json}\n{\n    \"Book\":\n    [\n        {\"title\":\"The Hobbit\",\"numberOfPages\":293},\n        {\"title\":\"The Lord Of The Rings\",\"numberOfPages\":1299}\n    ]\n}\n~~~~\n\nYou can watch full example at\n[github](https://github.com/lordofthejars/nosql-unit/tree/master/nosqlunit-demo)\n.\n\nReplica Set\n-----------\n### Introduction\n\nDatabase replication in **MongoDB** adds redundancy and high availability of the data.\nIn case of **MongoDB** instead of having traditional master-slave pattern architecture, it implements _Replica Set_ architecture,\nwhich can be understood as more sophisticated master-slave replication. For more information about _Replica Set_ read\n[mongoDB](http://docs.mongodb.org/manual/core/replication/)\n\n### Set up and Start Replica Set architecture\n\nIn **NoSQLUnit** we can define a replica set architecture and starting it up, so our tests are executed against a replica set servers instead of a single server. Due the nature of replica set system, we can only create a replica set of managed servers.\n\nSo let's see how to define an architecture and starting all related servers. The main class is *ReplicaSetManagedMongoDb* which manages lifecycle of all servers involved in replica set. To build a *ReplicaSetManagedMongoDb* class, *ReplicaSetBuilder* builder class is provided and it will allow us to define the replica set architecture. Using it we can set the eligible servers (those that can be primary or secondary), the only secondary servers, the arbiters, the hidden ones, and configure all of them with the attributes like priority, voters, or setting tags.\n\nSo let's see an example where we are defining two eligible servers and one arbiter in a replica set called rs-test.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.replicaset.ReplicaSetBuilder.replicaSet;\n\n@ClassRule\npublic static ReplicaSetManagedMongoDb replicaSetManagedMongoDb = replicaSet(\n            \"rs-test\")\n            .eligible(\n                    newManagedMongoDbLifecycle().port(27017)\n                            .dbRelativePath(\"rs-0\").logRelativePath(\"log-0\")\n                            .get())\n            .eligible(\n                    newManagedMongoDbLifecycle().port(27018)\n                            .dbRelativePath(\"rs-1\").logRelativePath(\"log-1\")\n                            .get())\n            .arbiter(\n                    newManagedMongoDbLifecycle().port(27019)\n                            .dbRelativePath(\"rs-2\").logRelativePath(\"log-2\")\n                            .get())\n            .get();\n~~~~\n\nNotice that you must define different port for each server and also a different database path. Also note that *ReplicaSetManagedMongoDb* won't let start executing tests until all replica set becomes stable (this can take some minutes).\n\nThen we only have to create a _MongoDbRule_ as usually which will populate defined data into replica set servers. For this case a new configuration builder is provided that  allows us to define the mongo servers location and the write concern used during seeding phase. By default _Aknownledge_ write concern is used.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.ReplicationMongoDbConfigurationBuilder.replicationMongoDbConfiguration;\n\n@Rule\npublic MongoDbRule mongoDbRule = newMongoDbRule().configure(\n                        replicationMongoDbConfiguration().databaseName(\"test\")\n                            .seed(\"localhost\", 27017)\n                            .seed(\"localhost\", 27018)\n                            .configure())\n                        .build();\n~~~~\n\nNow we have configured and deployed a replica set and populated them with the dataset.\n\nBut **NoSQLUnit** also provides an utility method to cause server failures. It is as easy as calling _shutdownServer_ method.\n\n~~~~ {.java}\nreplicaSetManagedMongoDb.shutdownServer(27017);\n~~~~\n\nKeep in mind two aspects of using this method:\n\n-   Because  _@ClassRule_ is used, we are responsible for restarting the system by calling _startServer_.\n-   System may become unstable and Mongo driver can throw many exceptions (that's normal because of MonitorThread) and even do some test fails. If you want to wait until all servers become stable again (in real life you won't have this possibility), you can use next call:\n\n~~~~ {.java}\nreplicaSetManagedMongoDb.waitUntilReplicaSetBecomesStable();\n~~~~\n\nAlso you can use **NoSQLUnit** to test your replica set deployment of remote servers. You can use MongoDbCommands to retrieve replica set configuration.\n\n~~~~ {.java}\nDBObject replicaSetGetStatus = MongoDbCommands.replicaSetGetStatus(mongoClient);\n~~~~\n\nAnd in previous case replicaSetGetStatus contains a json document with the format described in [MongoDB](http://docs.mongodb.org/manual/reference/replica-status/).\n\nYou can watch full example in [github](https://github.com/lordofthejars/nosql-unit/tree/master/nosqlunit-demo).\n\nSharding\n--------\n\n### Introduction\n\nSharding is another way of replication, but in this case we are scaling horizontally. MongoDB partitions a collection and stores the different portions on different machines. From a logical overview client only see one single database, but internally a cluster of machines are being used with data spread across all system.\n\nTo run sharding we must set up a sharded cluster. A sharded cluster is composed by next elements:\n\n-   shards which are _mongod_ instances that holds a portion of the database collections.\n-   config servers which stores metadata about the clusters.\n-   mongos servers determine the location of required data from shards.\n\nApart from setting up a sharding architecture, we also have to register each shard, enable sharding for database, enable sharding for each collection we want to partition,  and defining which element of the document is used to calculate the shard key.\n\nFor more information about _Sharding_ read [mongoDB](http://docs.mongodb.org/manual/sharding/)\n\n### Set up and Start Sharding\n\nIn **NoSQLUnit** we can define a sharding architecture and starting it up, so our tests are executed against it instead of a single server. Due the nature of sharding system, we can only create sharding for managed servers.\n\nSo let's see how to define an architecture and starting all related servers. The main class is *ShardedManagedMongoDb* which manages lifecycle of all servers involved in sharding (shards, configs and mongos). To build a *ShardedManagedMongoDb* class, *ShardedGroupBuilder* builder class is provided and it will allow us to define each server involved in sharding.\n\nLet's see an example on how to set up and start a system with two shards, one config server and one mongos.\n\n~~~~ {.java}\n@ClassRule\npublic static ShardedManagedMongoDb shardedManagedMongoDb = shardedGroup()\n                                .shard(newManagedMongoDbLifecycle().port(27018).dbRelativePath(\"rs-1\").logRelativePath(\"log-1\").get())\n                                .shard(newManagedMongoDbLifecycle().port(27019).dbRelativePath(\"rs-2\").logRelativePath(\"log-2\").get())\n                                .config(newManagedMongoDbLifecycle().port(27020).dbRelativePath(\"rs-3\").logRelativePath(\"log-3\").get())\n                                .mongos(newManagedMongosLifecycle().configServer(27020).get())\n                            .get();\n~~~~\n\nNotice that you must define different port for each server and also a different database path. Also note that in case of _mongos_ you must set the config server port, and is not necessary to set up the database path.\n\nAnd finally we only have to create a _MongoDbRule_ as usually which will populate defined data into sharding servers. For this case we must use the same builder used for replica set but enabling sharding. Keep in mind that in this case we only have to register the mongos instances, not shards or config servers.\n\n~~~~ {.java}\n@Rule\npublic MongoDbRule mongoDbRule = newMongoDbRule().configure(\n                                replicationMongoDbConfiguration().databaseName(\"test\")\n                                                   .enableSharding()\n                                                  .seed(\"localhost\", 27017)\n                                                  .configure())\n                                            .build();\n~~~~\n\nAnd finally the dataset format is changed from the standard one to allow us define which attributes are used as shards. Let's see an example:\n\n~~~~ {.json}\n{\n    \"collection_name\": {\n                \"shard-key-pattern\": [\"attribute_1\", \"attribute_2\"],\n                \"data\":\n                        [\n                            {\"attribute_1\":\"value_1\",\"attribute_2\":value_2, \"attribute_3\":\"value_3\"}\n                        ]\n            }\n}\n~~~~\n\nFor each collection you define which attributes are used for calculating the shard key by using _shard-key-pattern_ attribute, and finally using _data_ attribute we set the whole document which will be inserted into collection.\n\nIn case we use this dataset as expected dataset, _shard-key-pattern_ is ignored, and only _data_ document is used for comparison.\n\nReplicated Sharded Cluster\n--------------------------\n\n### Introduction\n\nThe third way of replication is an hybrid. Each shard contains a replica set with n-member replica set. And as sharding at least one _config_ server and one _mongos_ server is required.\n\nFor more information about _Replicated Sharded Cluster_ read [mongoDB](http://docs.mongodb.org/manual/tutorial/convert-replica-set-to-replicated-shard-cluster/)\n\n### Set up and Start Sharding\n\nIn **NoSQLUnit** we can define a replicated sharded cluster architecture and starting it up, so our tests are executed against it instead of a single server. Due the nature of replicated sharded cluster, we can only create sharding for managed servers.\n\nSo let's see how to define an architecture and starting all related servers. The main class is *ShardedManagedMongoDb* which manages lifecycle of all servers involved in sharding (shards, configs and mongos). To build a *ShardedManagedMongoDb* class, *ShardedGroupBuilder* builder class is provided and it will allow us to define each server involved in sharding, but in contrast of sharding, we need to add a replica set instead of a shard. For this reason *ReplicaSetManagedMongoDb* is also used.\n\nLet's see an example on how to set up two replicated sharded cluster, with one member each replica set, (of course in production environment you would have more), one config server and one mongos.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.mongodb.shard.ShardedGroupBuilder.shardedGroup;\nimport static com.lordofthejars.nosqlunit.mongodb.replicaset.ReplicaSetBuilder.replicaSet;\n\n@ClassRule\npublic static ShardedManagedMongoDb shardedManagedMongoDb = shardedGroup()\n                                    .replicaSet(replicaSet(\"rs-test-1\")\n                                            .eligible(\n                                                   newManagedMongoDbLifecycle()\n                                                    .port(27007).dbRelativePath(\"rs-0\").logRelativePath(\"log-0\")\n                                                    .get()\n                                                 )\n                                           .get())\n                                    .replicaSet(replicaSet(\"rs-test-2\")\n                                            .eligible(\n                                                newManagedMongoDbLifecycle()\n                                                    .port(27009).dbRelativePath(\"rs-0\").logRelativePath(\"log-0\")\n                                                    .get()\n                                                 )\n                                           .get())\n                                    .config(newManagedMongoDbLifecycle().port(27020).dbRelativePath(\"rs-3\").logRelativePath(\"log-3\").get())\n                                    .mongos(newManagedMongosLifecycle().configServer(27020).get())\n                                .get();\n~~~~\n\nNote that we are using the _replicaSet_ method of _shardedGroup_ to create a replica set inside a sharded, and then we use methods defined into *ReplicaSetBuilder* to configure the replica set.\n\nAnd finally we only have to create a _MongoDbRule_ as usually which will populate defined data into servers. For replicated sharded clusters we can use the same class and dataset as sharding.\n\n~~~~ {.java}\n@Rule\npublic MongoDbRule mongoDbRule = newMongoDbRule().configure(\n                                replicationMongoDbConfiguration().databaseName(\"test\")\n                                                   .enableSharding()\n                                                  .seed(\"localhost\", 27017)\n                                                  .configure())\n                                            .build();\n~~~~\n\nand\n\n~~~~ {.json}\n{\n    \"collection_name\": {\n                \"shard-key-pattern\": [\"attribute_1\", \"attribute_2\"],\n                \"data\":\n                        [\n                            {\"attribute_1\":\"value_1\",\"attribute_2\":value_2, \"attribute_3\":\"value_3\"}\n                        ]\n            }\n}\n~~~~\n\nNeo4j Engine\n============\n\nNeo4j\n=====\n\nNeo4j is a high-performance, *NoSQL* graph database with all the\nfeatures of a mature and robust database.\n\n**NoSQLUnit** supports *Neo4j* by using next classes:\n\n  ------------------ ------------------------------------------------------------\n  In Memory          com.lordofthejars.nosqlunit.neo4j.InMemoryNeo4j\n  Embedded           com.lordofthejars.nosqlunit.neo4j.EmbeddedNeo4j\n  Managed Wrapping   com.lordofthejars.nosqlunit.neo4j.ManagedWrappingNeoServer\n  Managed            com.lordofthejars.nosqlunit.neo4j.ManagedNeoServer\n  ------------------ ------------------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- ---------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.neo4j.Neo4jRule\n  ---------------------- ---------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use **NoSQLUnit** with Neo4j you only need to add next dependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-neo4j\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nDataset Format\n--------------\n\nDefault dataset file format in *Neo4j* module is\n[GraphML](http://graphml.graphdrawing.org/) . *GraphML* is a\ncomprehensive and easy-to-use file format for graphs.\n\nDatasets must have next [format](#ex.neo4j_dataset) :\n\n~~~~ {.xml}\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cgraphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\u003e\n    \u003ckey id=\"attr1\" for=\"edge\" attr.name=\"attr1\" attr.type=\"float\" attr.autoindexName=\"indexName\"/\u003e\n    \u003ckey id=\"attr2\" for=\"node\" attr.name=\"attr2\" attr.type=\"string\"/\u003e\n    \u003cgraph id=\"G\" edgedefault=\"directed\"\u003e\n        \u003cnode id=\"1\"\u003e\n            \u003cdata key=\"attr2\"\u003evalue1\u003c/data\u003e\n            \u003cindex name=\"mynodeindex\" key=\"mykey\"\u003emyvalue\u003c/index\u003e\n        \u003c/node\u003e\n        \u003cnode id=\"2\"\u003e\n            \u003cdata key=\"attr2\"\u003evalue2\u003c/data\u003e\n        \u003c/node\u003e\n        \u003cedge id=\"7\" source=\"1\" target=\"2\" label=\"label1\"\u003e\n            \u003cdata key=\"attr1\"\u003efloat\u003c/data\u003e\n            \u003cindex name=\"myrelindex\" key=\"mykey\"\u003emyvalue\u003c/index\u003e\n        \u003c/edge\u003e\n    \u003c/graph\u003e\n\u003c/graphml\u003e\n~~~~\n\nwhere:\n\n-   *graphml* : the root element of the GraphML document\n\n-   *key* : description for graph element properties, you must define if\n    property type is for nodes or relationships, name, and type of\n    element. In our case string, int, long, float, double and boolean\n    are supported.\n\n-   *graph* : the beginning of the graph representation. In our case\n    only one level of graphs are supported. Inner graphs will be\n    ignored.\n\n-   *node* : the beginning of a vertex representation. Please note that\n    id 0 is reserved for reference node, so cannot be used as id.\n\n-   *edge* : the beginning of an edge representation. Source and target\n    attributes are filled with node id. If you want to link with\n    reference node, use a 0 which is the id of root node. Note that\n    label attribute is not in defined in standard definition of GraphML\n    specification; GraphML supports adding new attributes to all GrpahML\n    elements, and label attribute has been added to facilitate the\n    creation of edge labels.\n\n-   *data* : the key/value data associated with a graph element. Data\n    value will be validated against type defined in key element.\n\n-   *attr.autoindexName* : this attribute is optional and can only set in *key* element.\n    It creates an index with given name for properties of that type for all nodes or edges.\n\n-   *index* :  This tag is optional and creates an index with given name, key and value in\n    the *node* or *edge* where it is declared.\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\nin-memory approach, embedded approach, managed approach or remote\napproach.\n\n#### In-memory Lifecycle\n\nTo configure **in-memory** approach you should only instantiate next\n[rule](#program.neo_inmemory_conf) :\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.InMemoryNeo4j.InMemoryNeo4jRuleBuilder.newInMemoryNeo4j;\n\n@ClassRule\npublic static InMemoryNeo4j inMemoryNeo4j = newInMemoryNeo4j().build();\n~~~~\n\n#### Embedded Lifecycle\n\nTo configure **embedded** approach you should only instantiate next\n[rule](#program.neo_embedded_conf) :\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.EmbeddedNeo4j.EmbeddedNeo4jRuleBuilder.newEmbeddedNeo4jRule;\n\n@ClassRule\npublic static EmbeddedNeo4j embeddedNeo4j = newEmbeddedNeo4jRule().build();\n~~~~\n\nBy default embedded *Neo4j* rule uses next default values:\n\n  ------------- ------------------------------------------------------------------------------------\n  Target path   This is the directory where *Neo4j* server is started and is `target/neo4j-temp` .\n  ------------- ------------------------------------------------------------------------------------\n\n  : Default Embedded Values\n\n\n\n#### Managed Lifecycle\n\nTo configure managed way, two possible approaches can be used:\n\nThe first one is using an **embedded database wrapped by a server** .\nThis is a way to give an embedded database visibility through network\n(internally we are creating a WrappingNeoServerBootstrapper instance) :\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.ManagedWrappingNeoServer.ManagedWrappingNeoServerRuleBuilder.newWrappingNeoServerNeo4jRule;\n\n@ClassRule\npublic static ManagedWrappingNeoServer managedWrappingNeoServer = newWrappingNeoServerNeo4jRule().port(8888).build();\n~~~~\n\nBy default wrapped managed *Neo4j* rule uses next default values, but\ncan be configured programmatically as shown in previous\n[example](#program.neo_wrapped_managed_conf) :\n\n  ------------- ----------------------------------------------------------------------------\n  Target path   The directory where *Neo4j* server is started and is `target/neo4j-temp` .\n  Port          Where server is listening incoming messages is 7474.\n  ------------- ----------------------------------------------------------------------------\n\n  : Default Wrapped Values\n\nThe second strategy is **starting and stopping an already installed\nserver** on executing machine, by calling start and stop command lines.\nNext [rule](#program.neo_managed_conf) should be registered:\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.ManagedNeoServer.Neo4jServerRuleBuilder.newManagedNeo4jServerRule;\n\n@ClassRule\npublic static ManagedNeoServer managedNeoServer = newManagedNeo4jServerRule().neo4jPath(\"/opt/neo4j\").build();\n~~~~\n\nBy default managed *Neo4j* rule uses next default values, but can be\nconfigured programmatically as shown in previous\n[example](#program.neo_managed_conf) :\n\n  ------------- -------------------------------------------------------------------------------------------------------------\n  Target path   This is the directory where *Neo4j* process will be started and by default is `target/neo4j-temp` .\n  Port          Where server is listening incoming messages is 7474.\n  Neo4jPath     *Neo4j* installation directory which by default is retrieved from `NEO4J_HOME` system environment variable.\n  ------------- -------------------------------------------------------------------------------------------------------------\n\n  : Default Managed Values\n\n\u003e **Warning**\n\u003e\n\u003e Versions prior to *Neo4j* 1.8, port cannot be configured from command\n\u003e line, and port should be changed manually in\n\u003e `conf/neo4j-server.properties` . Although this restriction, if you\n\u003e have configured *Neo4j* to run through a different port, it should be\n\u003e specified too in ManagedNeoServer rule.\n\n#### Remote Lifecycle\n\nConfiguring **remote** approach does not require any special rule\nbecause you (or System like Maven ) is the responsible of starting and\nstopping the server. This mode is used in deployment tests where you are\ntesting your application on real environment.\n\n### Configuring Neo4j Connection\n\nNext step is configuring **Neo4j** rule in charge of maintaining *Neo4j*\ngraph into known state by inserting and deleting defined datasets. You\nmust register Neo4jRule *JUnit* rule class, which requires a\nconfiguration parameter with information like host, port, uri or target\ndirectory.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects. Two\ndifferent kind of configuration builders exist.\n\n#### In-Memory/Embedded Connection\n\nThe first one is for configuring a connection to in-memory/embedded\n*Neo4j* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.EmbeddedNeoServerConfigurationBuilder.newEmbeddedNeoServerConfiguration;\n\n@Rule\npublic Neo4jRule neo4jRule = new Neo4jRule(newEmbeddedNeoServerConfiguration().build());\n~~~~\n\nIf you are only registering one embedded *Neo4j* instance like previous\n[example](#program.neo_embedded_conf) , calling `build` is enough. If\nyou are using more than one *Neo4j* embedded connection like explained\nin [Simultaneous Engine](#advanced.simultaneous-engine-title) section,\n`targetPath` shall be provided by using `buildFromTargetPath` method.\n\nIf you are using in-memory approach mixed with embedded approach, target\npath for in-memory instance can be found at\n`InMemoryNeo4j.INMEMORY_NEO4J_TARGET_PATH` variable.\n\n#### Managed/Remote Connection\n\nThe second one is for configuring a connection to remote *Neo4j* server\n(it is irrelevant at this level if it is wrapped or not). Default values\nare:\n\n  ---------------- -------------------------------\n  Connection URI   http://localhost:7474/db/data\n  Authentication   No authentication parameters.\n  ---------------- -------------------------------\n\n  : Default Managed Connection Values\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.ManagedNeoServerConfigurationBuilder.newManagedNeoServerConfiguration;\n\n@Rule\npublic Neo4jRule neo4jRule = new Neo4jRule(newManagedNeoServerConfiguration().build());\n~~~~\n\nor you can use the fast way:\n\n~~~~ {.java}\n@Rule\npublic Neo4jRule neo4jRule = newNeo4jRule().defaultManagedNeo4j();\n~~~~\n\n### Spring Connection\n\nIf you are plannig to use **Spring Data Neo4j**, you may require to use the *GraphDatabaseService* defined within Spring Application Context, mostly because you are defining an embedded connection using Spring namespace:\n\n~~~~ {.xml}\n\u003cneo4j:config storeDirectory=\"target/config-test\"/\u003e\n~~~~\n\nIn these cases you should use an special method which gets *GraphDatabaseService* instance instead of creating new one.\n\n~~~~ {.java}\n@Autowired\nprivate ApplicationContext applicationContext;\n\n@Rule\npublic Neo4jRule neo4jRule = newNeo4jRule().defaultSpringGraphDatabaseServiceNeo4j();\n~~~~\n\n\u003e Note that you need to autowire the application context, so **NoSQLUnit** can inject instance defined within application context into *Neo4jRule*.\n\n### Verifying Graph\n\n@ShouldMatchDataSet is also supported for *Neo4j* graphs but we should\nkeep in mind some considerations.\n\nTo compare two graphs, stored graph is exported into\n[GraphML](#ex.neo4j_dataset) format and then is compared with expected\n*GraphML* using *XmlUnit* framework. This approach implies two aspects\nto be considered, the first one is that although your graph does not\ncontains any connection to reference node, reference node will appear\ntoo with the form ( \\\u003cnode id=\"0\"\\\u003e\\\u003c/node\\\u003e ). The other aspect is that\nid's are *Neo4j's* internal id, so when you write the expected file,\nremember to follow the same id strategy followed by *Neo4j* so id\nattribute of each node could be matched correctly with generated output.\nInserted nodes' id starts from 1 (0 is reserved for reference node),\nmeanwhile edges starts from 0.\n\nThis way to compare graphs may change in future (although this strategy\nwill be always supported).\n\nAs I have noted in [verification section](#verifying_database) I find\nthat using @ShouldMatchDataSet is a bad approach during testing because\ntest readibility is affected negatively. So as general guide, my advice\nis to try to avoid using @ShouldMatchDataSet in your tests as much as\npossible.\n\n### Full Example\n\nTo show how to use **NoSQLUnit** with *Neo4j* , we are going to create a\nvery simple application that counts Neo's friends.\n\n[MatrixManager](#program.matrix_neo4j_manager) is the business class\nresponsible of inserting new friends and counting the number of Neo's\nfriends.\n\n~~~~ {.java}\npublic class MatrixManager {\n\n    public enum RelTypes implements RelationshipType {\n        NEO_NODE, KNOWS, CODED_BY\n    }\n\n    private GraphDatabaseService graphDb;\n\n    public MatrixManager(GraphDatabaseService graphDatabaseService) {\n        this.graphDb = graphDatabaseService;\n    }\n\n    public int countNeoFriends() {\n\n        Node neoNode = getNeoNode();\n        Traverser friendsTraverser = getFriends(neoNode);\n\n        return friendsTraverser.getAllNodes().size();\n\n    }\n\n    public void addNeoFriend(String name, int age) {\n        Transaction tx = this.graphDb.beginTx();\n        try {\n            Node friend = this.graphDb.createNode();\n            friend.setProperty(\"name\", name);\n            Relationship relationship = getNeoNode().createRelationshipTo(friend, RelTypes.KNOWS);\n            relationship.setProperty(\"age\", age);\n            tx.success();\n        } finally {\n            tx.finish();\n        }\n    }\n\n    private static Traverser getFriends(final Node person) {\n        return person.traverse(Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL_BUT_START_NODE,\n                RelTypes.KNOWS, Direction.OUTGOING);\n    }\n\n    private Node getNeoNode() {\n        return graphDb.getReferenceNode().getSingleRelationship(RelTypes.NEO_NODE, Direction.OUTGOING).getEndNode();\n    }\n\n}\n~~~~\n\nAnd now one unit test and one integration test is written:\n\nFor [unit](#program.matrix_neo4j_unit) test we are going to use embedded\napproach:\n\n~~~~ {.java}\nimport static org.junit.Assert.assertThat;\nimport static org.hamcrest.CoreMatchers.is;\nimport static com.lordofthejars.nosqlunit.neo4j.EmbeddedNeo4j.EmbeddedNeo4jRuleBuilder.newEmbeddedNeo4jRule;\nimport static com.lordofthejars.nosqlunit.neo4j.EmbeddedNeoServerConfigurationBuilder.newEmbeddedNeoServerConfiguration;\n\nimport javax.inject.Inject;\n\nimport org.junit.ClassRule;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.neo4j.graphdb.GraphDatabaseService;\n\nimport com.lordofthejars.nosqlunit.annotation.UsingDataSet;\nimport com.lordofthejars.nosqlunit.core.LoadStrategyEnum;\nimport com.lordofthejars.nosqlunit.neo4j.EmbeddedNeo4j;\nimport com.lordofthejars.nosqlunit.neo4j.Neo4jRule;\n\npublic class WhenNeoFriendsAreRequired {\n\n    @ClassRule\n    public static EmbeddedNeo4j embeddedNeo4j = newEmbeddedNeo4jRule().build();\n\n    @Rule\n    public Neo4jRule neo4jRule = new Neo4jRule(newEmbeddedNeoServerConfiguration().build(), this);\n\n    @Inject\n    private GraphDatabaseService graphDatabaseService;\n\n    @Test\n    @UsingDataSet(locations=\"matrix.xml\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    public void all_direct_and_inderectly_friends_should_be_counted() {\n        MatrixManager matrixManager = new MatrixManager(graphDatabaseService);\n        int countNeoFriends = matrixManager.countNeoFriends();\n        assertThat(countNeoFriends, is(3));\n    }\n\n}\n~~~~\n\nAnd as [integration test](#program.matrix_neo4j_integration) , the\nmanaged one:\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.neo4j.ManagedWrappingNeoServer.ManagedWrappingNeoServerRuleBuilder.newWrappingNeoServerNeo4jRule;\nimport static com.lordofthejars.nosqlunit.neo4j.ManagedNeoServerConfigurationBuilder.newManagedNeoServerConfiguration;\n\nimport javax.inject.Inject;\n\nimport org.junit.ClassRule;\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.neo4j.graphdb.GraphDatabaseService;\n\nimport com.lordofthejars.nosqlunit.annotation.ShouldMatchDataSet;\nimport com.lordofthejars.nosqlunit.annotation.UsingDataSet;\nimport com.lordofthejars.nosqlunit.core.LoadStrategyEnum;\nimport com.lordofthejars.nosqlunit.neo4j.ManagedWrappingNeoServer;\nimport com.lordofthejars.nosqlunit.neo4j.Neo4jRule;\n\npublic class WhenNeoMeetsANewFriend {\n\n    @ClassRule\n    public static ManagedWrappingNeoServer managedWrappingNeoServer = newWrappingNeoServerNeo4jRule().build();\n\n    @Rule\n    public Neo4jRule neo4jRule = new Neo4jRule(newManagedNeoServerConfiguration().build(), this);\n\n    @Inject\n    private GraphDatabaseService graphDatabaseService;\n\n    @Test\n    @UsingDataSet(locations=\"matrix.xml\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    @ShouldMatchDataSet(location=\"expected-matrix.xml\")\n    public void friend_should_be_related_into_neo_graph() {\n\n        MatrixManager matrixManager = new MatrixManager(graphDatabaseService);\n        matrixManager.addNeoFriend(\"The Oracle\", 4);\n    }\n\n}\n~~~~\n\nNote that in both cases we are using the same dataset as initial state,\nwhich looks like:\n\n~~~~ {.xml}\n\u003cgraphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n        http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\"\u003e\n    \u003ckey id=\"name\" for=\"node\" attr.name=\"name\" attr.type=\"string\"/\u003e\n    \u003ckey id=\"age\" for=\"edge\" attr.name=\"age\" attr.type=\"int\"/\u003e\n    \u003cgraph id=\"G\" edgedefault=\"directed\"\u003e\n        \u003cnode id=\"1\"\u003e\n            \u003cdata key=\"name\"\u003eThomas Anderson\u003c/data\u003e\n        \u003c/node\u003e\n        \u003cnode id=\"2\"\u003e\n            \u003cdata key=\"name\"\u003eTrinity\u003c/data\u003e\n        \u003c/node\u003e\n        \u003cnode id=\"3\"\u003e\n            \u003cdata key=\"name\"\u003eMorpheus\u003c/data\u003e\n        \u003c/node\u003e\n        \u003cnode id=\"4\"\u003e\n            \u003cdata key=\"name\"\u003eAgent Smith\u003c/data\u003e\n        \u003c/node\u003e\n        \u003cnode id=\"5\"\u003e\n            \u003cdata key=\"name\"\u003eThe Architect\u003c/data\u003e\n        \u003c/node\u003e\n        \u003cedge id=\"1\" source=\"0\" target=\"1\" label=\"NEO_NODE\"\u003e\n        \u003c/edge\u003e\n        \u003cedge id=\"2\" source=\"1\" target=\"2\" label=\"KNOWS\"\u003e\n            \u003cdata key=\"age\"\u003e3\u003c/data\u003e\n        \u003c/edge\u003e\n        \u003cedge id=\"3\" source=\"1\" target=\"3\" label=\"KNOWS\"\u003e\n            \u003cdata key=\"age\"\u003e5\u003c/data\u003e\n        \u003c/edge\u003e\n        \u003cedge id=\"4\" source=\"2\" target=\"3\" label=\"KNOWS\"\u003e\n            \u003cdata key=\"age\"\u003e18\u003c/data\u003e\n        \u003c/edge\u003e\n        \u003cedge id=\"5\" source=\"3\" target=\"4\" label=\"KNOWS\"\u003e\n            \u003cdata key=\"age\"\u003e20\u003c/data\u003e\n        \u003c/edge\u003e\n        \u003cedge id=\"6\" source=\"4\" target=\"5\" label=\"CODED_BY\"\u003e\n            \u003cdata key=\"age\"\u003e20\u003c/data\u003e\n        \u003c/edge\u003e\n    \u003c/graph\u003e\n\u003c/graphml\u003e\n~~~~\n\nCassandra Engine\n================\n\nCassandra\n=========\n\nCassandra is a BigTable data model running on an Amazon Dynamo-like\ninfrastructure.\n\n**NoSQLUnit** supports *Cassandra* by using next classes:\n\n  ---------- ---------------------------------------------------------\n  Embedded   com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandra\n  Managed    com.lordofthejars.nosqlunit.cassandra.ManagedCassandra\n  ---------- ---------------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- -----------------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.cassandra.CassandraRule\n  ---------------------- -----------------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use **NoSQLUnit** with Cassandra you only need to add next\ndependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-cassandra\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nDataset Format\n--------------\n\nDefault dataset file format in *Cassandra* module is json. To make\ncompatible **NoSQLUnit** with\n[Cassandra-Unit](https://github.com/jsevellec/cassandra-unit/) file\nformat, DataLoader of Cassandra-Unit project is used, so same json\nformat file is used.\n\nDatasets must have next [format](#ex.cassandra_dataset) :\n\n~~~~ {.json}\n{\n    \"name\" : \"\",\n    \"replicationFactor\" : \"\",\n    \"strategy\" : \"\",\n    \"columnFamilies\" : [{\n        \"name\" : \"\",\n        \"type\" : \"\",\n        \"keyType\" : \"\",\n        \"comparatorType\" : \"\",\n        \"subComparatorType\" : \"\",\n        \"defaultColumnValueType\" : \"\",\n        \"comment\" : \"\",\n        \"compactionStrategy\" : \"\",\n        \"compactionStrategyOptions\" : [{\n            \"name\" : \"\",\n            \"value\": \"\"\n        }],\n        \"gcGraceSeconds\" : \"\",\n        \"maxCompactionThreshold\" : \"\",\n        \"minCompactionThreshold\" : \"\",\n        \"readRepairChance\" : \"\",\n        \"replicationOnWrite\" : \"\",\n        \"columnsMetadata\" : [{\n            \"name\" : \"\",\n            \"validationClass : \"\",\n            \"indexType\" : \"\",\n            \"indexName\" : \"\"\n        },\n        ...\n        ]\n        \"rows\" : [{\n            \"key\" : \"\",\n            \"columns\" : [{\n                \"name\" : \"\",\n                \"value\" : \"\"\n            },\n            ...\n            ],\n            ...\n            // OR\n            ...\n            \"superColumns\" : [{\n                \"name\" : \"\",\n                \"columns\" : [{\n                    \"name\" : \"\",\n                    \"value\" : \"\"\n                },\n                ...\n                ]\n            },\n            ...\n            ]\n        },\n        ...\n        ]\n    },\n    ...\n    ]\n}\n~~~~\n\nSee [Cassandra-Unit\nDataset](https://github.com/jsevellec/cassandra-unit/wiki/What-can-you-set-into-a-dataSet)\nformat for more information.\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\nembedded approach, managed approach or remote approach.\n\n#### Embedded Lifecycle\n\nTo configure **embedded** approach you should only instantiate next\n[rule](#program.cassandra_embedded_conf) :\n\n~~~~ {.java}\n@ClassRule\npublic static EmbeddedCassandra embeddedCassandraRule = newEmbeddedCassandraRule().build();\n~~~~\n\nBy default embedded *Cassandra* rule uses next default values:\n\n  ------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------\n  Target path                    This is the directory where *Cassandra* server is started and is `target/cassandra-temp` .\n  Cassandra Configuration File   Location of yaml configuration file. By default a configuration file is provided with correct default parameters.\n  Host                           localhost\n  Port                           By default port used is 9171. Port cannot be configured, and cannot be changed if you provide an alternative Cassandra Configuration File.\n  ------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------\n\n  : Default Embedded Values\n\n#### Managed Lifecycle\n\nTo configure **managed** approach you should only instantiate next\n[rule](#program.cassandra_managed_conf) :\n\n~~~~ {.java}\n@ClassRule\npublic static ManagedCassandra managedCassandra = newManagedCassandraRule().build();\n~~~~\n\nBy default managed *Cassandra* rule uses next default values but can be\nconfigured programmatically:\n\n  --------------- ------------------------------------------------------------------------------------------------------------------------------\n  Target path     This is the directory where *Cassandra* server is started and is `target/cassandra-temp` .\n  CassandraPath   *Cassandra* installation directory which by default is retrieved from `CASSANDRA_HOME` system environment variable.\n  Port            By default port used is 9160. If port is changed in *Cassandra* configuration file, this port should be configured too here.\n  --------------- ------------------------------------------------------------------------------------------------------------------------------\n\n  : Default Managed Values\n\n\u003e **Warning**\n\u003e\n\u003e To start\n\u003e Cassandra\n\u003e java.home\n\u003e must be set. Normally this variable is already configured, you would\n\u003e need to do nothing.\n\n#### Remote Lifecycle\n\nConfiguring **remote** approach does not require any special rule\nbecause you (or System like Maven ) is the responsible of starting and\nstopping the server. This mode is used in deployment tests where you are\ntesting your application on real environment.\n\n### Configuring Cassandra Connection\n\nNext step is configuring **Cassandra** rule in charge of maintaining\n*Cassandra* graph into known state by inserting and deleting defined\ndatasets. You must register CassandraRule *JUnit* rule class, which\nrequires a configuration parameter with information like host, port, or\ncluster name.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects. Three\ndifferent kind of configuration builders exist.\n\n#### Embedded Connection\n\nThe first one is for configuring a connection to embedded *Cassandra* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandraConfigurationBuilder.newEmbeddedCassandraConfiguration;\n\n@Rule\npublic CassandraRule cassandraRule = new CassandraRule(newEmbeddedCassandraConfiguration().clusterName(\"Test Cluster\").build());\n~~~~\n\nHost and port parameters are already configured.\n\n#### Managed Connection\n\nThe first one is for configuring a connection to managed *Cassandra* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.cassandra.ManagedCassandraConfigurationBuilder.newManagedCassandraConfiguration;\n\n@Rule\npublic CassandraRule cassandraRule = new CassandraRule(newManagedCassandraConfiguration().clusterName(\"Test Cluster\").build());\n~~~~\n\nHost and port parameters are already configured with default parameters\nof managed lifecycle. If port is changed, this class provides a method\nto set it.\n\n#### Remote Connection\n\nConfiguring a connection to remote *Cassandra* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.cassandra.RemoteCassandraConfigurationBuilder.newRemoteCassandraConfiguration;\n\n@Rule\npublic CassandraRule cassandraRule = new CassandraRule(newRemoteCassandraConfiguration().host(\"192.168.1.1\").clusterName(\"Test Cluster\").build());\n~~~~\n\nPort parameter is already configured with default parameter of managed\nlifecycle. If port is changed, this class provides a method to set it.\nNote that host parameter must be specified in this case.\n\n### Verifying Data\n\n@ShouldMatchDataSet is also supported for *Cassandra* data but we should\nkeep in mind some considerations.\n\n\u003e **Warning**\n\u003e\n\u003e In\n\u003e NoSQLUnit\n\u003e , expectations can only be used over data, not over configuration\n\u003e parameters, so for example fields set in\n\u003e dataset\n\u003e file like compactionStrategy, gcGraceSeconds or maxCompactionThreshold\n\u003e are not used. Maybe in future will be supported but for now only data\n\u003e (keyspace, columnfamilyname, columns, supercolumns, ...) are\n\u003e supported.\n\n### Full Example\n\nTo show how to use **NoSQLUnit** with *Cassandra* , we are going to\ncreate a very simple application.\n\n[PersonManager](#program.person_cassandra_manager) is the business class\nresponsible of getting and updating person's car.\n\n~~~~ {.java}\npublic class PersonManager {\n\n    private ColumnFamilyTemplate\u003cString, String\u003e template;\n\n    public PersonManager(String clusterName, String keyspaceName, String host) {\n        Cluster cluster = HFactory.getOrCreateCluster(clusterName, host);\n        Keyspace keyspace = HFactory.createKeyspace(keyspaceName, cluster);\n\n        template = new ThriftColumnFamilyTemplate\u003cString, String\u003e(keyspace,\n                \"personFamilyName\",\n                                                               StringSerializer.get(),\n                                                               StringSerializer.get());\n\n    }\n\n    public String getCarByPersonName(String name) {\n        ColumnFamilyResult\u003cString, String\u003e queryColumns = template.queryColumns(name);\n        return queryColumns.getString(\"car\");\n    }\n\n    public void updateCarByPersonName(String name, String car) {\n        ColumnFamilyUpdater\u003cString, String\u003e createUpdater = template.createUpdater(name);\n        createUpdater.setString(\"car\", car);\n\n        template.update(createUpdater);\n    }\n\n}\n~~~~\n\nAnd now one unit test and one integration test is written:\n\nFor [unit](#program.person_cassandra_unit) test we are going to use\nembedded approach:\n\n~~~~ {.java}\nimport static org.junit.Assert.assertThat;\nimport static org.hamcrest.CoreMatchers.is;\n\nimport static com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandra.EmbeddedCassandraRuleBuilder.newEmbeddedCassandraRule;\nimport static com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandraConfigurationBuilder.newEmbeddedCassandraConfiguration;\n\nimport org.junit.ClassRule;\nimport org.junit.Rule;\nimport org.junit.Test;\n\nimport com.lordofthejars.nosqlunit.annotation.UsingDataSet;\nimport com.lordofthejars.nosqlunit.cassandra.CassandraRule;\nimport com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandra;\nimport com.lordofthejars.nosqlunit.core.LoadStrategyEnum;\n\npublic class WhenPersonWantsToKnowItsCar {\n\n    @ClassRule\n    public static EmbeddedCassandra embeddedCassandraRule = newEmbeddedCassandraRule().build();\n\n    @Rule\n    public CassandraRule cassandraRule = new CassandraRule(newEmbeddedCassandraConfiguration().clusterName(\"Test Cluster\").build());\n\n\n    @Test\n    @UsingDataSet(locations=\"persons.json\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    public void car_should_be_returned() {\n\n        PersonManager personManager = new PersonManager(\"Test Cluster\", \"persons\", \"localhost:9171\");\n        String car = personManager.getCarByPersonName(\"mary\");\n\n        assertThat(car, is(\"ford\"));\n\n    }\n\n}\n~~~~\n\nAnd as [integration test](#program.person_cassandra_integration) , the\nmanaged one:\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.cassandra.ManagedCassandraConfigurationBuilder.newManagedCassandraConfiguration;\nimport static com.lordofthejars.nosqlunit.cassandra.ManagedCassandra.ManagedCassandraRuleBuilder.newManagedCassandraRule;\n\nimport org.junit.ClassRule;\nimport org.junit.Rule;\nimport org.junit.Test;\n\nimport com.lordofthejars.nosqlunit.annotation.ShouldMatchDataSet;\nimport com.lordofthejars.nosqlunit.annotation.UsingDataSet;\nimport com.lordofthejars.nosqlunit.cassandra.CassandraRule;\nimport com.lordofthejars.nosqlunit.cassandra.ManagedCassandra;\nimport com.lordofthejars.nosqlunit.core.LoadStrategyEnum;\n\npublic class WhenPersonWantsToUpdateItsCar {\n\n    static {\n        System.setProperty(\"CASSANDRA_HOME\", \"/opt/cassandra\");\n    }\n\n    @ClassRule\n    public static ManagedCassandra managedCassandra = newManagedCassandraRule().build();\n\n    @Rule\n    public CassandraRule cassandraRule = new CassandraRule(newManagedCassandraConfiguration().clusterName(\"Test Cluster\").build());\n\n    @Test\n    @UsingDataSet(locations=\"persons.json\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    @ShouldMatchDataSet(location=\"expected-persons.json\")\n    public void new_car_should_be_updated() {\n\n        PersonManager personManager = new PersonManager(\"Test Cluster\", \"persons\", \"localhost:9171\");\n        personManager.updateCarByPersonName(\"john\", \"opel\");\n\n    }\n\n}\n~~~~\n\nNote that in both cases we are using the same dataset as initial state,\nwhich looks like:\n\n~~~~ {.json}\n{\n    \"name\" : \"persons\",\n    \"columnFamilies\" : [{\n        \"name\" : \"personFamilyName\",\n    \"keyType\" : \"UTF8Type\",\n    \"defaultColumnValueType\" : \"UTF8Type\",\n    \"comparatorType\" : \"UTF8Type\",\n        \"rows\" : [{\n            \"key\" : \"john\",\n            \"columns\" : [{\n                \"name\" : \"age\",\n                \"value\" : \"22\"\n            },\n            {\n                \"name\" : \"car\",\n                \"value\" : \"toyota\"\n            }]\n        },\n        {\n            \"key\" : \"mary\",\n            \"columns\" : [{\n                \"name\" : \"age\",\n                \"value\" : \"33\"\n            },\n            {\n                \"name\" : \"car\",\n                \"value\" : \"ford\"\n            }]\n        }]\n    }]\n}\n~~~~\n\nRedis Engine\n============\n\nRedis\n=====\n\nRedis is an open source, advanced key-value store. It is often referred\nto as a data structure server since keys can contain strings, hashes,\nlists, sets and sorted sets.\n\n**NoSQLUnit** supports *Redis* by using next classes:\n\n  ---------- -------------------------------------------------\n  Managed    com.lordofthejars.nosqlunit.redis.ManagedRedis\n  ---------- -------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- ---------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.redis.RedisRule\n  ---------------------- ---------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use **NoSQLUnit** with Redis you only need to add next dependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-redis\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nDataset Format\n--------------\n\nDefault dataset file format in *Redis* module is json.\n\nDatasets must have next [format](#ex.redis_dataset) :\n\n~~~~ {.json}\n{\n\"data\":[\n            {\"simple\": [\n                {\n                    \"key\":\"key1\",\n                    \"value\":\"value1\"\n                }\n                ]\n            },\n            {\"list\": [{\n                        \"key\":\"key3\",\n                        \"values\":[\n                            {\"value\":\"value3\"},\n                            {\"value\":\"value4\"}\n                        ]\n                      }]\n            },\n\n            {\"sortset\": [{\n                     \"key\":\"key4\",\n                     \"values\":[\n                           {\"score\":2, \"value\":\"value5\" },{\"score\":3, \"value\":1 }, {\"score\":1, \"value\":\"value6\" }]\n                 }]\n            },\n            {\"hash\": [\n                        {\n                            \"key\":\"user\",\n                            \"values\":[\n                                {\"field\":\"name\", \"value\":\"alex\"},\n                                {\"field\":\"password\", \"value\":\"alex\"}\n                            ]\n                        }\n                    ]\n            },\n            {\"set\":[{\n                        \"key\":\"key3\",\n                        \"values\":[\n                            {\"value\":\"value3\"},\n                            {\"value\":\"value4\"}\n                        ]\n                      }]\n            }\n]\n}\n~~~~\n\nRoot element must be called *data* , and then depending on kind of\nstructured data we need to store, one or more of next elements should\nappear. Note that key field is used to set the key of the element, and\nvalue field is used to set a value.\n\n-   *simple* : In case we want to store simple key/value elements. This\n    element will contain an array of key/value entries.\n\n-   *list* : In case we want to store a key with a list of values. This\n    element contain a *key* field for key name and *values* field with\n    an array of values.\n\n-   *set* In case we want to store a key within a set (no duplicates\n    allowed). Structure is the same as list element.\n\n-   *sortset* : In case we want to store a key within a sorted set. This\n    element contain the key, and an array of values, which each one,\n    apart from value field, also contain *score* field of type Number,\n    to set the order into sorted set.\n\n-   *hash* : In case we want to store a key within a map of field/value.\n    In this case *field* element set the field name, and *value* set the\n    value of that field.\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\nmanaged approach or remote approach.\n\n\n#### Managed Lifecycle\n\nTo configure **managed** approach you should only instantiate next\n[rule](#program.redis_managed_conf) :\n\n~~~~ {.java}\n@ClassRule\npublic static ManagedRedis managedRedis = newManagedRedisRule().redisPath(\"/opt/redis-2.4.16\").build();\n~~~~\n\nBy default managed *Redis* rule uses next default values but can be\nconfigured programmatically:\n\n  -------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n  Target path          This is the directory where *Redis* server is started and is `target/redis-temp` .\n  RedisPath            *Cassandra* installation directory which by default is retrieved from `REDIS_HOME` system environment variable.\n  Port                 By default port used is 6379. If port is changed in *Redis* configuration file, this port should be configured too here.\n  Configuration File   By default *Redis* can work with no configuration file, it uses default values, but if we need to start *Redis* with an specific configuration file located in any directory file path should be set.\n  -------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n  : Default Managed Values\n\n#### Remote Lifecycle\n\nConfiguring **remote** approach does not require any special rule\nbecause you (or System like Maven ) is the responsible of starting and\nstopping the server. This mode is used in deployment tests where you are\ntesting your application on real environment.\n\n### Configuring Redis Connection\n\nNext step is configuring **Redis** rule in charge of maintaining *Redis*\nstore into known state by inserting and deleting defined datasets. You\nmust register RedisRule *JUnit* rule class, which requires a\nconfiguration parameter with information like host, port, or cluster\nname.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects. Three\ndifferent kind of configuration builders exist.\n\n\n#### Managed Connection\n\nConfiguring a connection to managed *Redis* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.redis.ManagedRedisConfigurationBuilder.newManagedRedisConfiguration;\n\n@Rule\npublic RedisRule redisRule = new RedisRule(newManagedRedisConfiguration().build());\n\n~~~~\n\nHost and port parameters are already configured with default parameters\nof managed lifecycle. If port is changed, this class provides a method\nto set it.\n\n#### Remote Connection\n\nConfiguring a connection to remote *Redis* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.redis.RemoteRedisConfigurationBuilder.newRemoteRedisConfiguration;\n\n@Rule\npublic RedisRule redisRule = new RedisRule(newRemoteRedisConfiguration().host(\"192.168.1.1\").build());\n~~~~\n\nPort parameter is already configured with default parameter of managed\nlifecycle. If port is changed, this class provides a method to set it.\nNote that host parameter must be specified in this case.\n\n#### Shard Connection\n\nRedis connection also be configured as shard using ShardedJedis\ncapabilities.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.redis.RemoteRedisConfigurationBuilder.newRemoteRedisConfiguration;\n\n@Rule\npublic RedisRule redisRule = new RedisRule(newShardedRedisConfiguration()\n                .shard(host(\"127.0.0.1\"), port(ManagedRedis.DEFAULT_PORT))\n                    .password(\"a\")\n                    .timeout(1000)\n                    .weight(1000)\n                .shard(host(\"127.0.0.1\"), port(ManagedRedis.DEFAULT_PORT + 1))\n                    .password(\"b\")\n                    .timeout(3000)\n                    .weight(3000)\n                .build(););\n~~~~\n\nNote that only host and port is mandatory, the other ones uses default\nvalues.\n\n-   *password* : In case repository is protected with password this\n    attribute is used as password. Default values is null.\n\n-   *timeout* : Timeout for shard. By default timeout is set to 2\n    seconds.\n\n-   *weight* : The weight of that shard over the other ones. By default\n    is 1.\n\n### Verifying Data\n\n@ShouldMatchDataSet is also supported for *Redis* engine.\n\n### Full Example\n\nTo show how to use **NoSQLUnit** with *Redis* , we are going to create a\nvery simple application.\n\n[BookManager](#program.book_redis_manager) is the business class\nresponsible of inserting new books and finding books by their title.\n\n~~~~ {.java}\npublic class BookManager {\n\n    private static final String TITLE_FIELD_NAME = \"title\";\n    private static final String NUMBER_OF_PAGES = \"numberOfPages\";\n\n    private Jedis jedis;\n\n    public BookManager(Jedis jedis) {\n        this.jedis = jedis;\n    }\n\n    public void insertBook(Book book) {\n\n        Map\u003cString, String\u003e fields = new HashMap\u003cString, String\u003e();\n\n        fields.put(TITLE_FIELD_NAME, book.getTitle());\n        fields.put(NUMBER_OF_PAGES, Integer.toString(book.getNumberOfPages()));\n\n        jedis.hmset(book.getTitle(), fields);\n    }\n\n    public Book findBookByTitle(String title) {\n\n        Map\u003cString, String\u003e fields = jedis.hgetAll(title);\n        return new Book(fields.get(TITLE_FIELD_NAME), Integer.parseInt(fields.get(NUMBER_OF_PAGES)));\n\n    }\n\n}\n~~~~\n\nAnd now one integration test is written:\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.redis.RedisRule.RedisRuleBuilder.newRedisRule;\nimport static com.lordofthejars.nosqlunit.redis.ManagedRedis.ManagedRedisRuleBuilder.newManagedRedisRule;\n\nimport static org.junit.Assert.assertThat;\nimport static org.hamcrest.CoreMatchers.is;\n\nimport org.junit.ClassRule;\nimport org.junit.Rule;\nimport org.junit.Test;\n\nimport redis.clients.jedis.Jedis;\n\nimport com.lordofthejars.nosqlunit.annotation.UsingDataSet;\nimport com.lordofthejars.nosqlunit.core.LoadStrategyEnum;\nimport com.lordofthejars.nosqlunit.demo.model.Book;\nimport com.lordofthejars.nosqlunit.redis.ManagedRedis;\nimport com.lordofthejars.nosqlunit.redis.RedisRule;\n\npublic class WhenYouFindABook {\n\n    static {\n        System.setProperty(\"REDIS_HOME\", \"/opt/redis-2.4.16\");\n    }\n\n    @ClassRule\n    public static ManagedRedis managedRedis = newManagedRedisRule().build();\n\n    @Rule\n    public RedisRule redisRule = newRedisRule().defaultManagedRedis();\n\n    @Test\n    @UsingDataSet(locations=\"book.json\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    public void book_should_be_returned_if_title_is_in_database() {\n\n        BookManager bookManager = new BookManager(new Jedis(\"localhost\"));\n        Book findBook = bookManager.findBookByTitle(\"The Hobbit\");\n\n        assertThat(findBook, is(new Book(\"The Hobbit\", 293)));\n\n    }\n\n}\n~~~~\n\nAnd dataset used is:\n\n~~~~ {.json}\n{\n\"data\":[\n            {\"hash\": [\n                        {\n                            \"key\":\"The Hobbit\",\n                            \"values\":[\n                                {\"field\":\"title\", \"value\":\"The Hobbit\"},\n                                {\"field\":\"numberOfPages\", \"value\":\"293\"}\n                            ]\n                        }\n                    ]\n            }\n]\n}\n~~~~\n\nHBase Engine\n============\n\nHBase\n=====\n\n*Apache HBase* is an open-source, distributed, versioned, column-oriented\nstore.\n\n*NoSQLUnit* supports *HBase* by using next classes:\n\n  ---------- -------------------------------------------------\n  Embedded   com.lordofthejars.nosqlunit.hbase.EmbeddedHBase\n  Managed    com.lordofthejars.nosqlunit.hbase.ManagedHBase\n  ---------- -------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- ---------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.hbase.HBaseRule\n  ---------------------- ---------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use *NoSQLUnit* with HBase you only need to add next dependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-hbase\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nDataset Format\n--------------\n\nDefault dataset file format in *HBase* module is json. Dataset in HBase\nis the same used by\n[Cassandra-Unit](https://github.com/jsevellec/cassandra-unit/) but not all\nfields are supported. Only fields available in TSV HBase application can\nbe set into dataset.\n\nSo as summary datasets must have next [format](#ex.hbase_dataset) :\n\n~~~~ {.json}\n{\n    \"name\" : \"tablename\",\n    \"columnFamilies\" : [{\n        \"name\" : \"columnFamilyName\",\n        \"rows\" : [{\n            \"key\" : \"key1\",\n            \"columns\" : [{\n                \"name\" : \"columnName\",\n                \"value\" : \"columnValue\"\n            },\n            ...\n            ]\n        },\n        ...\n        ]\n    },\n    ...\n    ]\n}\n~~~~\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\nembedded approach, managed approach or remote approach.\n\n#### Embedded Lifecycle\n\nTo configure *embedded* approach you should only instantiate next\n[rule](#program.hbase_embedded_conf) :\n\n~~~~ {.java}\n@ClassRule\npublic static EmbeddedHBase embeddedHBase = newEmbeddedHBaseRule().build();\n~~~~\n\nBy default embedded *Embedded* rule uses HBaseTestingUtility default\nvalues:\n\n  ------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n  Target path        This is the directory where *HBase* stores data and is `target/data` .\n  Host               localhost\n  Port               By default port used is 60000.\n  File Permissions   Depending on your umask configuration, HBaseTestingUtility will create some directories that will not be accessible during runtime. By default this value is set to 775, but depending on your OS you may require a different value.\n  ------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n  : Default Embedded Values\n\n#### Managed Lifecycle\n\nTo configure *managed* approach you should only instantiate next\n[rule](#program.hbase_managed_conf) :\n\n~~~~ {.java}\n@ClassRule\npublic static ManagedHBase managedHBase = newManagedHBaseServerRule().build();\n~~~~\n\nBy default managed *HBase* rule uses next default values but can be\nconfigured programmatically:\n\n  --------------- ---------------------------------------------------------------------------------------------------------------------------\n  Target path     This is the directory where *HBase* server is started and is `target/hbase-temp` .\n  HBasePath       *HBase* installation directory which by default is retrieved from `HBASE_HOME` system environment variable.\n  Port            By default port used is 60000. If port is changed in *HBase* configuration file, this port should be configured too here.\n  --------------- ---------------------------------------------------------------------------------------------------------------------------\n\n  : Default Managed Values\n\n\u003e **Warning**\n\u003e\n\u003e To start\n\u003e HBASE\n\u003e JAVA\\_HOME\n\u003e must be set. Normally this variable is already configured, so you would\n\u003e need to do nothing.\n\n#### Remote Lifecycle\n\nConfiguring *remote* approach does not require any special rule because\nyou (or System like Maven ) is the responsible of starting and stopping\nthe server. This mode is used in deployment tests where you are testing\nyour application on real environment.\n\n### Configuring HBase Connection\n\nNext step is configuring *HBase* rule in charge of maintaining *HBase*\ncolumns into known state by inserting and deleting defined datasets. You\nmust register HBaseRule *JUnit* rule class, which requires a\nconfiguration parameter with some information.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects. Three\ndifferent kind of configuration builders exist.\n\n#### Embedded Connection\n\nThe first one is for configuring a connection to embedded *HBase* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.hbase.EmbeddedHBase.EmbeddedHBaseRuleBuilder.newEmbeddedHBaseRule;\n\n@Rule\npublic HBaseRule hBaseRule = newHBaseRule().defaultEmbeddedHBase();\n~~~~\n\nEmbedded HBase does not require any special parameter. Configuration\nobject is copied from Embedded rule directly to HBaseRule.\n\n#### Managed Connection\n\nThis is for configuring a connection to managed *HBase* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.hbase.ManagedHBaseConfigurationBuilder.newManagedHBaseConfiguration;\n\n@Rule\npublic HBaseRule hbaseRule = new HBaseRule(newManagedHBaseConfiguration().build());\n~~~~\n\nBy default configuration used is the one loaded by calling\nHBaseConfiguration.create() method.\n[HBaseConfiguration.create()](http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/HBaseConfiguration.html#create())\nwhich uses hbase-site.xml and hbase-default.xml classpath files.\n\nBut also a method `setProperty` method is provided to modify any\nparameter of generated configuration object.\n\n#### Remote Connection\n\nConfiguring a connection to remote *HBase* uses same approach like\nManagedHBase configuration object but using\ncom.lordofthejars.nosqlunit.hbase.RemoteHBaseConfigurationBuilder class\ninstead of\ncom.lordofthejars.nosqlunit.hbase.ManagedHBaseConfigurationBuilder. .\n\n\u003e **Warning**\n\u003e\n\u003e Working with Apache HBase required a bit of knowledge about how it\n\u003e works. For example your /etc/hosts file cannot contain a reference to\n\u003e your host name with ip 127.0.1.1.\n\u003e\n\u003e Moreover *NoSQLUnit* uses *HBase-0.94.1* and this version should be\n\u003e also installed in your computer to work with managed or remote approach. If you\n\u003e install another version, you should exclude these artifacts from\n\u003e *NoSQLUnit* dependencies, and add the new ones manually to your pom\n\u003e file.\n\n### Verifying Data\n\n@ShouldMatchDataSet is also supported for *HBase* data but we should\nkeep in mind some considerations.\n\nIf you plan to verify data with @ShouldMatchDataSet in Managed and\nRemote approach, you should enable Aggregate coprocessor by editing\nhbase-site-xml file and adding next lines:\n\n~~~~ {.xml}\n\u003cproperty\u003e\n    \u003cname\u003ehbase.coprocessor.user.region.classes\u003c/name\u003e\n    \u003cvalue\u003eorg.apache.hadoop.hbase.coprocessor.AggregateImplementation\u003c/value\u003e\n\u003c/property\u003e\n~~~~\n\n### Full Example\n\nTo show how to use *NoSQLUnit* with *HBase* , we are going to create a\nvery simple application.\n\n[PersonManager](#program.person_hbase_manager) is the business class\nresponsible of getting and updating person's car.\n\n~~~~ {.java}\npublic class PersonManager {\n\n    private Configuration configuration;\n\n    public PersonManager(Configuration configuration) {\n        this.configuration = configuration;\n    }\n\n    public String getCarByPersonName(String personName) throws IOException {\n        HTable table = new HTable(configuration, \"person\");\n        Get get = new Get(\"john\".getBytes());\n        Result result = table.get(get);\n\n        return new String(result.getValue(toByteArray().convert(\"personFamilyName\"), toByteArray().convert(\"car\")));\n    }\n\n    private Converter\u003cString, byte[]\u003e toByteArray() {\n        return new Converter\u003cString, byte[]\u003e() {\n\n            @Override\n            public byte[] convert(String element) {\n                return element.getBytes();\n            }\n        };\n    }\n\n}\n~~~~\n\nAnd now one unit test is written:\n\nFor [unit](#program.person_hbase_unit) test we are going to use embedded\napproach:\n\n~~~~ {.java}\npublic class WhenPersonWantsToKnowItsCar {\n\n    @ClassRule\n    public static EmbeddedHBase embeddedHBase = newEmbeddedHBaseRule().build();\n\n    @Rule\n    public HBaseRule hBaseRule = newHBaseRule().defaultEmbeddedHBase(this);\n\n    @Inject\n    private Configuration configuration;\n\n\n    @Test\n    @UsingDataSet(locations=\"persons.json\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    public void car_should_be_returned() throws IOException {\n\n        PersonManager personManager = new PersonManager(configuration);\n        String car = personManager.getCarByPersonName(\"john\");\n\n        assertThat(car, is(\"toyota\"));\n    }\n\n}\n~~~~\n\nAnd dataset used is:\n\n~~~~ {.json}\n{\n    \"name\" : \"person\",\n    \"columnFamilies\" : [{\n        \"name\" : \"personFamilyName\",\n        \"rows\" : [{\n            \"key\" : \"john\",\n            \"columns\" : [{\n                \"name\" : \"age\",\n                \"value\" : \"22\"\n            },\n            {\n                \"name\" : \"car\",\n                \"value\" : \"toyota\"\n            }]\n        },\n        {\n            \"key\" : \"mary\",\n            \"columns\" : [{\n                \"name\" : \"age\",\n                \"value\" : \"33\"\n            },\n            {\n                \"name\" : \"car\",\n                \"value\" : \"ford\"\n            }]\n        }]\n    }]\n}\n~~~~\n\nCouchDB Engine\n==============\n\nCouchDB\n=======\n\n*CouchDB* is a *NoSQL* database that stores structured data as *JSON-like*\ndocuments with dynamic schemas.\n\n**NoSQLUnit** supports *CouchDB* by using next classes:\n\n  --------- ----------------------------------------------------\n  Managed   com.lordofthejars.nosqlunit.couchdb.ManagedCouchDb\n  --------- ----------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- -------------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.couchdb.CouchDbRule\n  ---------------------- -------------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use **NoSQLUnit** with CouchDB you only need to add next dependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-couchdb\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nDataset Format\n--------------\n\nDefault dataset file format in *CouchDB* module is *json* .\n\nDatasets must have next [format](#ex.couchdb_dataset) :\n\n~~~~ {.json}\n{\n    \"data\":\n            [\n                {\"attribute1\":\"value1\", \"atribute2\":\"value2\", ...},\n                {...}\n            ]\n}\n~~~~\n\nNotice that if attributes value are integers, double quotes are not\nrequired.\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\n**managed** approach or **remote** approach.\n\nThere is no *CouchDB* inmemory instance, so only managed or remote\nlifecycle can be used.\n\nTo configure the **managed** way, you should use ManagedCouchDb rule and\nmay require some [configuration](#program.couchdb_managed_conf)\nparameters.\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.couchdb.ManagedCouchDb.ManagedCouchDbRuleBuilder.newManagedCouchDbRule;\n\n@ClassRule\npublic static ManagedCouchDb managedCouchDb = newManagedCouchDbRule().couchDbPath(\"/usr/local\").build();\n~~~~\n\nBy default managed *CouchDB* rule uses next default values:\n\n-   *CouchDB* installation directory is retrieved from `COUCHDB_HOME`\n    system environment variable.\n\n-   Target path, that is the directory where *CouchDB* server is\n    started, is `target/couchdb-temp` .\n\n-   Port where *CouchDB* will be started. Note that this parameter is\n    used only as information, if you change port from configuration file\n    you should change this parameter too. By default*CouchDB* server is\n    started at `5984` .\n\nConfiguring **remote** approach does not require any special rule\nbecause you (or System like Maven ) is the responsible of starting and\nstopping the server. This mode is used in deployment tests where you are\ntesting your application on real environment.\n\n### Configuring CouchDB Connection\n\nNext step is configuring ***CouchDB*** rule in charge of maintaining\n*CouchDB* database into known state by inserting and deleting defined\ndatasets. You must register CouchDbRule *JUnit* rule class, which\nrequires a configuration parameter with information like host, port or\ndatabase name.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects.\n\n  ---------------------- -------------------------------\n  URI                    http://localhost5984\n  Authentication         No authentication parameters.\n  Enable SSL             false.\n  Relaxed SSL Settings   false.\n  Caching                True.\n  ---------------------- -------------------------------\n\n  : Default Managed Configuration Values\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.couchdb.CouchDbRule.CouchDbRuleBuilder.newCouchDbRule;\n\n@Rule\npublic CouchDbRule couchDbRule = newCouchDbRule().defaultManagedCouchDb(\"books\");\n~~~~\n\n### Complete Example\n\nConsider a library application, which apart from multiple operations, it\nallow us to add new books to system. Our\n[model](#example.couchdb_book_model) is as simple as:\n\n~~~~ {.java}\npublic class Book {\n\n    private String title;\n\n    private int numberOfPages;\n\n    public Book(String title, int numberOfPages) {\n        super();\n        this.title = title;\n        this.numberOfPages = numberOfPages;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public void setNumberOfPages(int numberOfPages) {\n        this.numberOfPages = numberOfPages;\n    }\n\n\n    public String getTitle() {\n        return title;\n    }\n\n    public int getNumberOfPages() {\n        return numberOfPages;\n    }\n}\n~~~~\n\nNext business [class](#example.couchdb_book_manager) is the responsible\nof managing access to *CouchDB* server:\n\n~~~~ {.java}\nprivate CouchDbConnector connector;\n\n    public BookManager(CouchDbConnector connector)  {\n        this.connector = connector;\n    }\n\n    public void create(Book book) {\n        connector.create(MapBookConverter.toMap(book));\n    }\n\n    public Book findBookById(String id) {\n        Map\u003cString, Object\u003e map = connector.get(Map.class, id);\n        return MapBookConverter.toBook(map);\n    }\n~~~~\n\nAnd now it is time for testing. In next\n[test](#example.couchdb_test_find_book) we are going to validate that a\nbook is found into database.\n\n~~~~ {.java}\npublic class WhenYouFindBooksById {\n\n    @ClassRule\n    public static ManagedCouchDb managedCouchDb = newManagedCouchDbRule().couchDbPath(\"/usr/local\").build();\n\n    @Rule\n    public CouchDbRule couchDbRule = newCouchDbRule().defaultManagedCouchDb(\"books\");\n\n    @Inject\n    private CouchDbConnector couchDbConnector;\n\n    @Test\n    @UsingDataSet(locations=\"books.json\", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)\n    public void identified_book_should_be_returned() {\n\n        BookManager bookManager = new BookManager(couchDbConnector);\n        Book book = bookManager.findBookById(\"1\");\n\n        assertThat(book.getTitle(), is(\"The Hobbit\"));\n        assertThat(book.getNumberOfPages(), is(293));\n\n    }\n\n}\n~~~~\n\n~~~~ {.json}\n{\n    \"data\":\n            [\n                {\"_id\":\"1\", \"title\":\"The Hobbit\",\"numberOfPages\":\"293\"}\n            ]\n}\n~~~~\n\nYou can watch full example at\n[github](https://github.com/lordofthejars/nosql-unit/tree/master/nosqlunit-demo)\n.\n\nInfinispan Engine\n============\n\nInfinispan\n=====\n\nInfinispan is an open-source transactional in-memory key/value NoSQL datastore \u0026 Data Grid.\n\n*NoSQLUnit* supports *Infinispan* by using next classes:\n\n  ---------- -------------------------------------------------\n  Embedded   com.lordofthejars.nosqlunit.infinispan.EmbeddedInfinispan\n  Managed    com.lordofthejars.nosqlunit.infinispan.ManagedInfinispan\n  ---------- -------------------------------------------------\n\n  : Lifecycle Management Rules\n\n  ---------------------- ---------------------------------------------\n  NoSQLUnit Management   com.lordofthejars.nosqlunit.infinispan.InfinispanRule\n  ---------------------- ---------------------------------------------\n\n  : Manager Rule\n\nMaven Setup\n-----------\n\nTo use *NoSQLUnit* with HBase you only need to add next dependency:\n\n~~~~ {.xml}\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.lordofthejars\u003c/groupId\u003e\n    \u003cartifactId\u003enosqlunit-infinispan\u003c/artifactId\u003e\n    \u003cversion\u003e${version.nosqlunit}\u003c/version\u003e\n\u003c/dependency\u003e\n~~~~\n\nDataset Format\n--------------\n\nDefault dataset file format in *Infinispan* module is json. With this dataset you can define the key and the value that will be inserted into *Infinispan*. Value can be a simple types like Integer, String, ..., collection types, like set and list implementations or objects (using default Jackson rules (no annotations required).\n\nSo as summary datasets must have next [format](#ex.infinispan_dataset) :\n\n~~~~ {.json}\n{\n    \"data\": [\n                {\n                    \"key\":\"alex\",\n                    \"implementation\":\"com.lordofthejars.nosqlunit.demo.infinispan.User\",\n                    \"value\": {\n                                \"name\":\"alex\",\n                                \"age\":32\n                             }\n                },\n                {\n                    \"key\":\"key1\",\n                    \"value\":1\n                },\n                {\n                    \"key\":\"key2\",\n                    \"implementation\":\"java.util.HashSet\",\n                    \"value\": [{\"value\":\"a\"},{\"value\":\"b\"}]\n                }\n\n            ]\n}\n~~~~\n\nNote that first key is inserting an object. You should set its implementation, and set the object properties in json format so Jackson can create the required object. User object only contains getter and setters of properties.\nThe second key is a simple key, in this case an integer.\nThe third one is a set of strings. See that we must provide the implementation of collection or an *ArrayList* will be used as default. Also you can define objects instead of simple types.\n\nGetting Started\n---------------\n\n### Lifecycle Management Strategy\n\nFirst step is defining which lifecycle management strategy is required\nfor your tests. Depending on kind of test you are implementing (unit\ntest, integration test, deployment test, ...) you will require an\nembedded approach, managed approach or remote approach.\n\n#### Embedded Lifecycle\n\nTo configure *embedded* approach you should only instantiate next\n[rule](#program.infinispan_embedded_conf) :\n\n~~~~ {.java}\n@ClassRule\n    public static final EmbeddedInfinispan EMBEDDED_INFINISPAN = newEmbeddedInfinispanRule().build();\n~~~~\n\nBy default embedded *Embedded* rule uses EmbeddedCacheManager with default\nvalues:\n\n  ------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n  Target path        This is the directory used for starting Embedded Infinispan and by default is target/infinispan-test-data/impermanent-db,  .\n  Configuration File Configuration file used by Infinispan for configuring the grid. By default no configuration file is provided and default *Infinispan* internal values are used.\n  ------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\n  : Default Embedded Values\n\n#### Managed Lifecycle\n\nTo configure *managed* approach you should only instantiate next\n[rule](#program.infinispan_managed_conf) :\n\n~~~~ {.java}\n@ClassRule\n    public static ManagedInfinispan managedInfinispan = newManagedInfinispanRule().infinispanPath(\"/opt/infinispan-5.1.6\").build();\n~~~~\n\nBy default managed *Infinispan* rule uses next default values but can be\nconfigured programmatically:\n\n  --------------- ---------------------------------------------------------------------------------------------------------------------------\n  Target path     This is the directory where *Infinispan* server is started and is `target/infinispan-temp` .\n  InfinispanPath  *Infinispan* installation directory which by default is retrieved from `INFINISPAN_HOME` system environment variable.\n  Port            By default port used is 11222.\n  Protocol\t\t  By default hotrod is used and internally **NoSQLUnit** uses hotrod too, so it should be desirable to no change it.\n  --------------- ---------------------------------------------------------------------------------------------------------------------------\n\n#### Remote Lifecycle\n\nConfiguring *remote* approach does not require any special rule because\nyou (or System like Maven ) is the responsible of starting and stopping\nthe server. This mode is used in deployment tests where you are testing\nyour application on real environment.\n\n### Configuring Infinispan Connection\n\nNext step is configuring *Infinispan* rule in charge of maintaining *Infinispan*\ncolumns into known state by inserting and deleting defined datasets. You\nmust register InfinispanRule *JUnit* rule class, which requires a\nconfiguration parameter with some information.\n\nTo make developer's life easier and code more readable, a fluent\ninterface can be used to create these configuration objects. Three\ndifferent kind of configuration builders exist.\n\n#### Embedded Connection\n\nThe first one is for configuring a connection to embedded *Infinispan* .\n\n~~~~ {.java}\ncom.lordofthejars.nosqlunit.infinispan.InfinispanRule.InfinispanRuleBuilder.newInfinispanRule;\n\n@Rule\npublic InfinispanRule infinispanRule = newInfinispanRule().defaultEmbeddedInfinispan();\n~~~~\n\nEmbedded Infinispan does not require any special parameter. But you can use com.lordofthejars.nosqlunit.infinispan.EmbeddedInfinispanConfigurationBuilder class for creatinga  custom configuration object for setting cache name.\n\n#### Managed Connection\n\nThis is for configuring a connection to managed *Infinispan* .\n\n~~~~ {.java}\nimport static com.lordofthejars.nosqlunit.infinispan.ManagedInfinispanConfigurationBuilder.newManagedInfinispanConfiguration;\n\n@Rule\npublic InfinispanRule infinispanRule = newInfinispanRule.configure(newManagedHBaseConfiguration().build()).build();\n~~~~\n\nBy default the port used is the 11222, and configuration is used the default ones provided by *Infinispan*. You can also set the configuration properties (used by hotrod client) and cache name.\n\n#### Remote Connection\n\nConfiguring a connection to remote *Infinispan* uses same approach like\nManagedInfinispan configuration object but using\ncom.lordofthejars.nosqlunit.infinispan.RemoteInfinispanConfigurationBuilder class. .\n\n### Verifying Data\n\n@ShouldMatchDataSet is also supported for *Infinispan* data but we should\nkeep in mind some considerations.\n\nIf you plan to verify data with @ShouldMatchDataSet and POJO objects *equals* method is used, so implements it accordantly.\n\n\n### Full Example\n\nTo show how to use *NoSQLUnit* with *Infinispan* , we are going to create a\nvery simple application.\n\n[UserManager](#program.user_infinispan_manager) is the business class\nresponsible of getting and addinga user to the system.\n\n~~~~ {.java}\npublic class UserManager {\n\n    private BasicCache\u003cString, User\u003e cache;\n\n    public UserManager(BasicCache\u003cString, User\u003e cache) {\n        this.cache = cache;\n    }\n\n    public void addUser(User user) {\n        this.cache.put(user.getName(), user);\n    }\n\n    public User getUser(String name) {\n        return this.cache.get(name);\n    }\n\n}\n~~~~\n\nAnd now one unit test is written:\n\nFor [unit](#program.user_infinispan_unit) test we are going to use embedded\napproach:\n\n~~~~ {.ja","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flordofthejars%2Fnosql-unit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flordofthejars%2Fnosql-unit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flordofthejars%2Fnosql-unit/lists"}