Spring Data MongoDB – Unit Testing using in memory Fongo

This post is about unit testing spring data mongodb using in-memory java implementation of Mongo called Fongo.

Complete source code is in github.

https://github.com/sanjuthomas/spring-data-mongodb

Tools and Libraries used.

  1. Fongo (1.1.2)
  2. Spring Data MongoDB (1.2.2.RELEASE)
  3. Mongo java driver (2.11.0)
  4. Junit (4.8.1)
  5. Spring Test (3.2.4.RELEASE)
  6. No SQL Unit MongoDB (0.7.7)
  7. Java 7

We will save and load Trade object using TradeRepository. Test data will be saved and loaded into in-memory Fongo.

Spring Data MongoDB Repository Class.

package com.ourownjava.spring.data.mongo.repository;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.ourownjava.spring.data.mongo.model.Trade;
/**
* Spring Data MongoDB Repository Example.
*
* @author ourownjava.com
*
*/
public interface TradeRepository extends MongoRepository{
public List findByTraderId(final String traderId);
public List findByExchangeCode(final String exchangeId);
}

Trade Class. (Document)

package com.ourownjava.spring.data.mongo.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
/**
*
* @author ourownjava.com
*
*/
@Document(collection = "trade")
public class Trade {
@Id
private String id;
private String traderId;
private Double value;
private String exchangeCode;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getTraderId() {
return traderId;
}
public void setTraderId(final String traderId) {
this.traderId = traderId;
}
public Double getValue() {
return value;
}
public void setValue(final Double value) {
this.value = value;
}
public String getExchangeCode() {
return exchangeCode;
}
public void setExchangeCode(final String exchangeCode) {
this.exchangeCode = exchangeCode;
}
}

TradeRepository test class.

package com.ourownjava.spring.data.mongo.repository;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static com.lordofthejars.nosqlunit.mongodb.MongoDbRule.MongoDbRuleBuilder.newMongoDbRule;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.foursquare.fongo.Fongo;
import com.lordofthejars.nosqlunit.annotation.ShouldMatchDataSet;
import com.lordofthejars.nosqlunit.annotation.UsingDataSet;
import com.lordofthejars.nosqlunit.mongodb.MongoDbRule;
import com.mongodb.Mongo;
import com.ourownjava.spring.data.mongo.model.Trade;
/**
* Spring Data MongoDB Repository Unit testcase.
*
* @author ourownjava.com
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class TestTradeRepository {
@Autowired
private ApplicationContext applicationContext;
@Rule
public MongoDbRule mongoDbRule = newMongoDbRule().defaultSpringMongoDb(
"trade-db");
@Autowired
private TradeRepository tradeRepository;
@Test
@ShouldMatchDataSet(location = "/testData/trade-t1.json")
public void shouldSaveTrade(){
tradeRepository.save(createTrade());
}
@Test
@UsingDataSet(locations = {"/testData/trade-t1.json"})
public void shouldFindByTraderId(){
final List trades = tradeRepository.findByTraderId("papjac");
assertNotNull(trades);
assertTrue(trades.size() > 0);
assertEquals("papjac", trades.get(0).getTraderId());
}
@Test
@UsingDataSet(locations = {"/testData/trade-t1.json"})
public void shouldFindByExchangeCode(){
final List trades = tradeRepository.findByExchangeCode("NYSE");
assertNotNull(trades);
assertTrue(trades.size() > 0);
assertEquals("NYSE", trades.get(0).getExchangeCode());
}
private Trade createTrade(){
final Trade trade = new Trade();
trade.setId("t1");
trade.setTraderId("papjac");
trade.setExchangeCode("NYSE");
trade.setValue(90.3);
return trade;
}
@Configuration
@EnableMongoRepositories
@ComponentScan(basePackageClasses = { TradeRepository.class })
static class MongoConfiguration extends AbstractMongoConfiguration {
@Override
protected String getDatabaseName() {
return "trade-db";
}
@Override
public Mongo mongo() {
return new Fongo("trade-test").getMongo();
}
@Override
protected String getMappingBasePackage() {
return "com.ourownjava.spring.data.mongo";
}
}
}

Test Data.

{
"trade": [
{
"_id": "t1",
"traderId": "papjac",
"value": 90.3,
"exchangeCode": "NYSE"
}
]
}

We are using two annotations in the test class.

  1. ShouldMatchDataSet
  2. UsingDataSet

ShouldMatchDataSet is used to compare the saved document against the test data. UsingDataSet will load the test data into in-memory Fongo.

Project Structure.

spring data mongodb unit testing using in-memory fongo

4 thoughts on “Spring Data MongoDB – Unit Testing using in memory Fongo

  1. Thanks your post was a great help. But I did initially have a problem resolving the Mongo bean and had to annotate the mongo() method with @Bean. It’s probably due to some change in a later version of the libraries.

  2. Hi Thanks for the tutorial.

    I am using the following code snippet:

    @Test
    @UsingDataSet(locations = {“/testData/course.json”})
    public void testAllCourses(){

    List courseList=service.findAllCourse();
    assertNotNull(courseList);

    assertTrue(courseList.size() > 0);
    assertEquals(“000005″, courseList.get(0).getCourseId());

    }

    After running it the following exception is thrown:

    java.lang.ClassCastException: java.lang.String cannot be cast to com.mongodb.DBObject

    Can you please suggest?