Mostrando entradas con la etiqueta junit. Mostrar todas las entradas
Mostrando entradas con la etiqueta junit. Mostrar todas las entradas

martes, junio 27, 2017

Lifecycle of JUnit 5 Extension Model


JUnit5 final release is around the corner (currently it is M4), and I have started playing with it a bit on how to write extensions.

In JUnit5, instead of dealing with Runners, Rules, ClassRules and so on, you've got a single Extension API to implement your own extensions.

JUnit5 provides several interfaces to hook in its lifecycle. For example you can hook to Test Instance Post-processing to invoke custom initialization methods on the test instance, or Parameter Resolution for dynamically resolving test method parameters at runtime. And of course the typical ones like hooking before all tests are executed, before a test is executed, after a test is executed and so on so far, a complete list can be found at http://junit.org/junit5/docs/current/user-guide/#extensions-lifecycle-callbacks

But in which point of the process it is executed each of them? To test it I have just created an extension that implements all interfaces and each method prints who is it.


Then I have created a JUnit5 Test suite containing two tests:

So after executing this suite, what it is the output? Let's see it. Notice that for sake of readability I have added some callouts on terminal output.


<1> First test that it is run is AnotherLoggerExtensionTest. In this case there is only one simple test, so the lifecycle of extension is BeforeAll, Test Instance-Post-Processing, Before Each, Before Test Execution, then the test itself is executed, and then all After callbacks.

<2> Then the LoggerExtensionTest is executed. First test is not a parametrized test, so events related to parameter resolution are not called. Before the test method is executed, test instance post-processing is called, and after that all before events are thrown. Finally the test is executed with all after events.

<3> Second test contains requires a parameter resolution. Parameter resolvers are run after Before events and before executing the test itself.

<4> Last test throws an exception. Test Execution Exception is called after test is executed but before After events.

Last thing to notice is that BeforeAll and AfterAll events are executed per test class and not suite.

The JUnit version used in this example is org.junit.jupiter:junit-jupiter-api:5.0.0-M4

We keep learning,
Alex
That's why we won't back down, We won't run and hide, 'Cause these are the things we can't deny, I'm passing over you like a satellite (Satellite - Rise Against)
Music: https://www.youtube.com/watch?v=6nQCxwneUwA

Follow me at

lunes, octubre 21, 2013

Resistance is futile mocks will be assimilated



My slides of my recently talk about testing at Codemotion Madrid. The summary of the talk was:

Everybody is unit testing, everybody is mocking. Everybody mocks database access, software dependencies, external systems, container services, ... to test what? You end up testing a bit of business logic and writing a lot of test code, when in production this code will run within a container under different circumstances. In this talk we are going to see how some tools like Arquillian, Byteman, NoSQLUnit and other programs, may help us writing real tests in a Java EE environment.


I would like to say thank you very much to Laura and all the team to arrange such a great conferences. Hope to see you in next Codemotion.

lunes, abril 22, 2013

NoSQLUnit 0.7.6 Released


NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.7.6 release, next changes has been implemented:

We keep learning,
Alex.

De dia vivire pensando en tu sonrisa, De noche las estrellas me acompañaran, Seras como un luz que alumbra en mi destino, Me voy pero te juro que mañana volvere (Un Beso Y Una Flor - Niño Bravo)

Music: http://www.youtube.com/watch?v=Q3UqusEWGeo

martes, marzo 19, 2013

Testing Spring Data Neo4j Applications with NoSQLUnit

Spring Data Neo4j


Spring Data Neo4j is the project within Spring Data project which provides an extension to the Spring programming model for writing applications that uses Neo4j as graph database.
To write tests using NoSQLUnit for Spring Data Neo4j applications, you do need nothing special apart from considering that Spring Data Neo4j uses a special property called type in graph nodes and relationships which stores the fully qualified classname of that entity.

Apart from type property at node/relationship level, we also need to create one index for nodes and one index for relationships. In case of nodes, types index name is required, meanwhile rel_types is required for relationships. In both cases we must set key value to className and value to full qualified classname.

Note Type mapping
IndexingNodeTypeRepresentationStrategy and IndexingRelationshipTypeRepresentationStrategy are used as default type mapping implementation, but you can also use SubReferenceNodeTypeRepresentationStrategy which stores entity types in a tree in the graph representing the type and interface hierarchy, or you can customize even more by implementing NodeTypeRepresentationStrategy interface.

Hands on Work

Application

Starfleet has asked us to develop an application for storing all starfleet members, with their relationship with other starfleet members, and the ship where they serve.

The best way to implement this requirement is using Neo4j database as backend system. Moreover Spring Data Neo4j is used at persistence layer.

This application is modelized into two Java classes, one for members and another one for starships. Note that for this example there are no properties in relationships, so only nodes are modelized.

Member class

@NodeEntity
public class Member {

        private static final String COMMANDS = "COMMANDS";

        @GraphId Long nodeId;

        private String name;

        private Starship assignedStarship;

        public Member() {
                super();
        }

        public Member(String name) {
                this.name = name;
        }

        @Fetch @RelatedTo(type=COMMANDS, direction=Direction.OUTGOING)
        private Set<Member> commands;

        public void command(Member member) {
                this.commands.add(member);
        }

        public Set<Member> commands() {
                return this.commands;
        }

        public Starship getAssignedStarship() {
                return assignedStarship;
        }

        public String getName() {
                return name;
        }

        public void assignedIn(Starship starship) {
                this.assignedStarship = starship;
        }

        //Equals and Hash methods
}
Starship class

@NodeEntity
public class Starship {

        private static final String ASSIGNED = "assignedStarship";

        @GraphId Long nodeId;

        private String starship;

        public Starship() {
                super();
        }

        public Starship(String starship) {
                this.starship = starship;
        }

        @RelatedTo(type = ASSIGNED, direction=Direction.INCOMING)
        private Set<Member> crew;

        public String getStarship() {
                return starship;
        }

        public void setStarship(String starship) {
                this.starship = starship;
        }

        //Equals and Hash methods
}

Apart from model classes, we also need two repositories for implementing CRUD operations, and spring context xml file. Spring Data Neo4j uses Spring Data Commons infrastructure allowing us to create interface based compositions of repositories, providing default implementations for certain operations.

MemberRepository class

public interface MemberRepository extends GraphRepository<Member>,
                RelationshipOperationsRepository<Member> {

        Member findByName(String name);

}

See that apart from operations provided by GrapRepository interface like save, findAll, findById, … we are defining one query method too called findByName. Spring Data Neo4j repositories (and most of Spring Data projects) provide a mechanism to define queries using the known Ruby on Rails approach for defining finder queries.

StarshipRepository class

public interface StarshipRepository extends GraphRepository<Starship>,
                RelationshipOperationsRepository<Starship> {
}
application-context file

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/data/neo4j
           http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">

     <context:component-scan base-package="com.lordofthejars.nosqlunit.springdata.neo4j"/>
     <context:annotation-config/>

     <neo4j:repositories base-package="com.lordofthejars.nosqlunit.springdata.repository"/>

</beans>

Testing

Unit Testing

As it has been told previously, for writing datasets for Spring Data Neo4j, we don’t have to do anything special beyond creating node and relationship properties correctly and defining the required indexes. Let’s see the dataset used to test the findByName method by seeding Neo4j database.

star-trek-TNG-dataset.xml file

<?xml version="1.0" ?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
     <key id="name" for="node" attr.name="name" attr.type="string"></key>
     <key id="__type__" for="node" attr.name="__type__" attr.type="string"></key>
     <key id="starship" for="node" attr.name="starship" attr.type="string"></key>
     <graph id="G" edgedefault="directed">

       <node id="3">
        <data key="__type__">com.lordofthejars.nosqlunit.springdata.neo4j.Member</data>
        <data key="name">Jean-Luc Picard</data>
        <index name="__types__" key="className">com.lordofthejars.nosqlunit.springdata.neo4j.Member</index>
      </node>

      <node id="1">
        <data key="__type__">com.lordofthejars.nosqlunit.springdata.neo4j.Member</data>
        <data key="name">William Riker</data>
        <index name="__types__" key="className">com.lordofthejars.nosqlunit.springdata.neo4j.Member</index>
      </node>

      <node id="4">
        <data key="__type__">com.lordofthejars.nosqlunit.springdata.neo4j.Starship</data>
        <data key="starship">NCC-1701-E</data>
        <index name="__types__" key="className">com.lordofthejars.nosqlunit.springdata.neo4j.Starship</index>
      </node>

      <edge id="11" source="3" target="4" label="assignedStarship"></edge>
      <edge id="12" source="1" target="4" label="assignedStarship"></edge>
      <edge id="13" source="3" target="1" label="COMMANDS"></edge>

    </graph>
</graphml>

See that each node has at least one type property with full qualified classname and an index with name types, key className and full qualified classname as value.
Next step is configuring application context for unit tests.

application-context-embedded-neo4j.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/data/neo4j
           http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">


        <import resource="classpath:com/lordofthejars/nosqlunit/springdata/neo4j/application-context.xml"/>
        <neo4j:config storeDirectory="target/config-test"/>

</beans>
Notice that we are using Neo4j namespace for instantiating an embedded Neo4j database.
And now we can write the JUnit test case:

WhenInformationAboutAMemberIsRequired

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("application-context-embedded-neo4j.xml")
public class WhenInformationAboutAMemberIsRequired {

        @Autowired
        private MemberRepository memberRepository;
        @Autowired
        private StarshipRepository starshipRepository;

        @Autowired
        private ApplicationContext applicationContext;

        @Rule
        public Neo4jRule neo4jRule = newNeo4jRule()
                        .defaultSpringGraphDatabaseServiceNeo4j();

        @Test
        @UsingDataSet(locations = "star-trek-TNG-dataset.xml", loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
        public void information_about_starship_where_serves_and_members_under_his_service_should_be_retrieved()  {

                Member jeanLuc = memberRepository.findByName("Jean-Luc Picard");

                assertThat(jeanLuc, is(createMember("Jean-Luc Picard")));
                assertThat(jeanLuc.commands(), containsInAnyOrder(createMember("William Riker")));

                Starship starship = starshipRepository.findOne(jeanLuc.getAssignedStarship().nodeId);
                assertThat(starship, is(createStarship("NCC-1701-E")));
        }

        private Object createStarship(String starship) {
                return new Starship(starship);
        }

        private static Member createMember(String memberName) {
                return new Member(memberName);
        }
}

There are some important points in the previous class to take under consideration:
  1. Recall that we need to use Spring ApplicationContext object to retrieve embedded Neo4j instance defined into Spring application context.
  2. Since lifecycle of database is managed by Spring Data container, there is no need to define any NoSQLUnit lifecycle manager.

Integration Test

Unit tests are usually run against embedded in-memory instances, but in production environment you may require access to external Neo4j servers by using Rest connection, or in case of Spring Data Neo4j instantiating SpringRestGraphDatabase class. You need to write tests to validate that your application still works when you integrate your code with a remote server, and this tests are typically known as integration tests.
To write integration tests for our application is as easy as defining an application context with SpringRestGraphDatabase and allow NoSQLUnit to control the lifecycle of Neo4j database.

.application-context-managed-neo4j.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/data/neo4j
           http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd">


        <import resource="classpath:com/lordofthejars/nosqlunit/springdata/neo4j/application-context.xml"/>

        <bean id="graphDatabaseService" class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase">
                <constructor-arg index="0" value="http://localhost:7474/db/data"></constructor-arg>
        </bean>
        <neo4j:config graphDatabaseService="graphDatabaseService"/>

</beans>

Note how instead of registering an embedded instance, we are configuring SpringRestGraphDatabase class to connect to localhost server. And let’s implement an integration test which verifies that all starships can be retrieved from Neo4j server.

WhenInformationAboutAMemberIsRequired

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("application-context-managed-neo4j.xml")
public class WhenInformationAboutStarshipsAreRequired {

        @ClassRule
        public static ManagedNeoServer managedNeoServer = newManagedNeo4jServerRule()
                        .neo4jPath(
                                        "/Users/alexsotobueno/Applications/neo4j-community-1.7.2")
                        .build();

        @Autowired
        private StarshipRepository starshipRepository;

        @Autowired
        private ApplicationContext applicationContext;

        @Rule
        public Neo4jRule neo4jRule = newNeo4jRule()
                        .defaultSpringGraphDatabaseServiceNeo4j();

        @Test
        @UsingDataSet(locations = "star-trek-TNG-dataset.xml", loadStrategy = LoadStrategyEnum.CLEAN_INSERT)
        public void information_about_starship_where_serves_and_members_under_his_service_should_be_retrieved() {

                EndResult<Starship> allStarship = starshipRepository.findAll();

                assertThat(allStarship, containsInAnyOrder(createStarship("NCC-1701-E")));

        }

        private Object createStarship(String starship) {
                return new Starship(starship);
        }

}

Because defaultSpringGraphDatabaseServiceNeo4j method returns a GraphDatabaseService instance defined into application context, in our case it will return the defined SpringRestGraphDatabase instance.

Conclusions

There is not much difference between writing tests for none Spring Data Neo4j applications than the ones they use it. Only keep in mind to define correctly the type property and create required indexes.

Also see that from the point of view of NoSQLUnit there is no difference between writing unit or integration tests, apart of lifecycle management of the database engine.

Download Code

We keep learning,
Alex.
Gonna rise up, Burning black holes in dark memories, Gonna rise up, Turning mistakes into gold (Rise - Eddie Vedder)

Music: http://www.youtube.com/watch?v=uuVf4xiRsJQ

lunes, enero 07, 2013

NoSQLUnit 0.7.3 Released



NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.7.3 release, next changes has been added:

  • Support for Infinispan.
  • Adding the possibility to add custom insertion and comparison methods for each engine. Thanks to Bob Tiernay for the idea. https://github.com/lordofthejars/nosql-unit/issues/45
  • Adding the possibility to avoid NoSQLUnit injects fields annotated by @Inject by using @ByContainer annotation.  Very useful for Spring Framework Tests, Arquillian Tests or Needle Tests.
  • Removed JMockMongo as embedded Mongo implementation for Fongo project. Users should not notice any difference from the point of view of NoSQLUnit. Thank to Bob Tiernay for providing this valuable information about Fongo.
  • Updated mongo-java-driver to 2.10.1.
  • Updated neo4j to 1.8.
  • Fixed bug #46 thanks to MrKeyholder for discovering and attaching the solution code.
We keep learning,
Alex.
Fiery mountain beneath the moon, The words unspoken, we'll be there soon, For home a song that echoes on, And all who find us will know the tune. (The Lonely Mountain - Neil Finn)

domingo, octubre 14, 2012

NoSQLUnit 0.5.0 released


NoSQLUnit is a JUnit extension to make writing unit and high-level tests of systems that use NoSQL as backend easier. Visit official page for more information.

In current release instead of supporting one new engine, I focused on implementing an embedded in-memory Redis engine based on Jedis.  Read in documentation the limitations on current implementation. And of course now NoSQLUnit also supports embedded Redis apart from Managed and Remote, you only have to register EmbeddedRedis rule to use it.
@ClassRule
public static EmbeddedRedis embeddedRedis = newEmbeddedRedisRule().build();
Moreover I have fixed some issues with Managed Cassandra lifecycle.

Also I have extended the support to embedded Neo4j engine by allowing the use of instance defined into Spring context file using spring data namespace. See next example that NoSQLUnit will populate data into instance defined in application context.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd
            http://www.springframework.org/schema/data/neo4j
            http://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd">

    <context:annotation-config/>
    <neo4j:config storeDirectory="target/config-test"/>

</beans>
And in your test you only have to define SpringEmbeddedNeo4j rule passing the application context object where Neo4j is defined.
@Autowired
private ApplicationContext applicationContext;
...
@ClassRule
SpringEmbeddedNeo4j springEmbeddedGds = newSpringEmbeddedNeo4jRule().beanFactory(applicationContext).build();
And finally in this version of NoSQLUnit, I have implemented that we can use Shard connections provided by Jedis library to populate defined data into different shards. The only thing you should do is changing configuration instance of RedisRule to ShardedRedisConfiguration. See next simple example:
@Rule
public RedisRule redisRule = new RedisRule(newShardedRedisConfiguration()
         .shard(host("127.0.0.1"), port(ManagedRedis.DEFAULT_PORT))
             .password("a")
             .timeout(1000)
             .weight(1000)
         .shard(host("127.0.0.1"), port(ManagedRedis.DEFAULT_PORT + 1))
             .password("b")
             .timeout(3000)
             .weight(3000)
         .build());

And that's all for current version.

Next release 0.6.0 will contain support for HBase. Moreover there are an open poll to vote which engine would you like to see in next releases:


Stay in touch with the project and of course I am opened to any ideas that you think that could make NoSQLUnit better.

We keep learning,
Alex.

Well, these boots are made for walking, and that's just what they'll do, One of these days these boots are gonna walk all over you. (These Boots Are Made For Walkin' - Nancy Sinatra)
Music: http://www.youtube.com/watch?v=SbyAZQ45uww

lunes, septiembre 24, 2012

Testing client side of RESTful services


People tell me A and B, They tell me how I have to see, Things that I have seen already clear, So they push me then from side to side (I Want Out - Helloween)
Develop an application that uses RESTful web API may imply developing server and client side. Writing integration tests for server side can be as easy as using Arquillian to start up server and REST-assured to test that the services works as expected. The problem is how to test the client side. In this post we are going to see how to test the client side apart from using mocks.

As a brief description, to test client part, what we need is a local server which can return recorded JSON responses. The rest-client-driver is a library which simulates a RESTful service. You can set expectations on the HTTP requests you want to receive during a test. So it is exactly what we need for our java client side. Note that this project is really helpful to write tests when we are developing RESTful web clients for connecting to services developed by third parties like Flickr Rest API, Jira Rest API, Github ...

First thing to do is adding rest-client-driver dependency:

Next step we are going to create a very simple Jersey application which simply invokes a get method to required URI.

And now we want to test that invokeGetMethod really gets the required resource. Let's suppose that this method in production code will be responsible of getting all issues name from a project registered on github.

Now we can start to write the test:

  • We use ClientDriverRule  @Rule annotation to add the client-driver to a test.
  • And then using methods provided by RestClientDriver class, expectations are recorded.
  • See how we are setting the base URL using driver.getBaseUrl()
With rest-client-driver we can also record http status response using giveEmptyResponse method:


And obviously we can record a put action:

Note that in this example, we are setting that our request should contain given message body to response a 204 status code.

This is a very simple example, but keep in mind that also works with libraries like gson or jackson. Also rest-driver project comes with a module that can be used to assert server responses (like REST-assured project) but this topic will be addressed into another post.

I wish you have found this post useful.

We keep learning,
Alex.

miércoles, septiembre 05, 2012

NoSQLUnit 0.4.1 Released



Yo no soy marinero, Yo no soy marinero, soy capitan, Soy capitan, soy capitan, Bamba, bamba (La Bamba - Ritchie Valens)
NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.4.1 release, after supporting Cassandra in 0.4.0 version, one new NoSQL system is supported and is Redis.

Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.

As all databases supported by NoSQLUnit, two set of rules are provided to write Redis tests:

First set of JUnit Rules are those responsible of managing database lifecycle; basically starting and stopping Redis instance.

  • Currently Redis does not support embedded lifecycle. For this reason I am developing an embedded in-memory Redis mock. It is based in Jedis library, and will be released in next version. Issue #22.
  • Managed: com.lordofthejars.nosqlunit.redis.ManagedRedis
Second set of rules are those responsible of maintaining database into known state;
  • NoSQLUnit Management: com.lordofthejars.nosqlunit.redis.RedisRule
And finally default dataset file format in Redis is json

We will use a very simple example used in Redis tutorial as an example of how to write unit tests for systems that uses Redis database as backend.

First of all, dataset used to maintain Redis into known state:


and finally the test case:


Next release 0.4.2 will contain fixes for issues #22, #23, #24 and #25. Moreover there are an open a poll to vote which engine would you like to see in 0.5.0 release:

Vote For Next Engine

Stay in touch with the project and of course I am opened to any ideas that you think that could make NoSQLUnit better.

Music: http://www.youtube.com/watch?v=Jp6j5HJ-Cok

miércoles, agosto 22, 2012

NoSQLUnit 0.4.0 Released



All across the nation such a strange vibration, People in motion, There's a whole generation with a new explanation, People in motion people in motion (San Francisco - Scott McKenzie)
NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.4.0 release, one new NoSQL system is supported and is Cassandra.

Cassandra is a BigTable data model running on an Amazon Dynamo-like infrastructure.

As all databases supported by NoSQLUnit, two set of rules are provided to write Cassandra tests:

First set of JUnit Rules are those responsible of managing database lifecycle; basically starting and stopping Cassandra instance.
  • Embedded: com.lordofthejars.nosqlunit.cassandra.EmbeddedCassandra
  • Managed: com.lordofthejars.nosqlunit.cassandra.ManagedCassandra
Depending on kind of tests you are implementing (unit test, integration test, deployment tests, …) you will require an embedded, managed or remote approach. Note that for now I haven to implemented an In-Memory approach because there is no in-memory Cassandra  instance, but embedded strategy for unit tests will be the better one. 

Second set of rules are those responsible of maintaining database into known state;
  • NoSQLUnit Management: com.lordofthejars.nosqlunit.cassandra.CassandraRule
And finally default dataset file format in Cassandra is json. To make compatible NoSQLUnit with Cassandra-Unit file format, DataLoader of Cassandra-Unit project is used, so same json format file is used.

We will use a very simple example used in Cassandra tutorial as an example of how to write unit tests for systems that uses Cassandra database as backend.

First of all, dataset used to maintain Cassandra into known state:


and finally the test case:


Next release 0.4.1 will contain some internal changes, but no support for new engine. And after these changes, new engines will be supported. Moreover I have decided to open a poll to vote which engine would you like to see in 0.4.2 release:

Visit Poll Here

Stay in touch with the project and of course I am opened to any ideas that you think that could make NoSQLUnit better.

Music: http://www.youtube.com/watch?v=bch1_Ep5M1s

martes, agosto 07, 2012

NoSQLUnit 0.3.2 Released


Yo no te pido la luna, tan solo quiero amarte. Quiero ser esa locura que vibra muy dentro de tí (Yo No Te Pido La Luna - Sergio Dalma)

Update: 0.3.3 version has been released providing In-Memory Neo4j lifecycle support.

NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.3.2 release, one new NoSQL system is supported and is Neo4j.

Neo4j is a high-performance, NoSQL graph database with all the features of a mature and robust database.

As all databases supported by NoSQLUnit, two set of rules are provided to write Neo4j tests:

First set of JUnit Rules are those responsible of managing database lifecycle; basically starting and stopping Neo4j.
  • Embedded: com.lordofthejars.nosqlunit.neo4j.EmbeddedNeo4j
  • Managed Wrapping: com.lordofthejars.nosqlunit.neo4j.ManagedWrappingNeoServer
  • Managed: com.lordofthejars.nosqlunit.neo4j.ManagedNeoServer
Depending on kind of test you are implementing (unit test, integration test, deployment test, ...) you will require an embedded approach, managed approach or  remote approach. Note that for now I have not implementated of a Neo4j in-memory database at this time (0.3.3 will do), but embedded strategy for unit tests will be the better one. As Neo4j developers will know, you can start remote Neo4j server by calling start/stop scripts (Managed way) or by using an embedded database wrapper by a server (Managed Wrapping way), both of them are supported by NoSQLUnit.

Second set of rules are those responsible of maintaining database into known state;
  • NoSQLUnit Management: com.lordofthejars.nosqlunit.neo4j.Neo4jRule
And finally default dataset file format in Neo4j is GraphML. GraphML is a comprehensive and easy-to-use file format for graphs.


We will use the example of finding Neo's friends as an example of how to write unit tests for systems that uses Neo4j databases as backend.

First of all dataset used to maintain Neo4j into known state:


and finally the test case:

Next release will support Cassandra. Stay in touch with the project and of course I am opened to any ideas that you think that could make NoSQLUnit better.

lunes, julio 02, 2012

NoSQLUnit 0.3.1 Released




And the last known survivor, Stalks his prey in the night, And he's watching us all with the, Eye of the tiger (Eye Of The Tiger - Survivor)

NoSQLUnit is a JUnit extension to make writing unit and integration tests of systems that use NoSQL backend easier. Visit official page for more information.

In 0.3.1 release, two new features among some bug fixes has been implemented. These two new features are the ability of create simultaneous connections to different backends at same test, and partial support for jsr-330 specification.


Simultaneous engines

Sometimes applications will contain more than one NoSQL engine, for example some parts of your model will be expressed better as a graph ( Neo4J for example), but other parts will be more natural in a column way (for example using Cassandra ). NoSQLUnit supports this kind of scenarios by providing in integration tests a way to not load all datasets into one system, but choosing which datasets are stored in each backend.

For declaring more than one engine, you must give a name to each database Rule using connectionIdentifier() method in configuration instance.


And also you need to provide an identified dataset for each engine, by using withSelectiveLocations attribute of @UsingDataSet annotation. You must set up the pair "named connection" / datasets.


In example we are refreshing database declared on previous example with data located at test3 file.

Also works in expectations annotation:


When you use more than one engine at a time you should take under consideration next rules:
  • If location attribute is set, it will use it and will ignore withSelectiveMatcher attribute data. Location data is populated through all registered systems.
  • If location is not set, then system tries to insert data defined in withSelectiveMatcher attribute to each backend.
  • If withSelectiveMatcher attribute is not set, then default strategy is taken. Note that default strategy will replicate all datasets to defined engines.
You can also use the same approach for inserting data into same engine but in different databases. If you have one MongoDb instance with two databases, you can also write tests for both databases at one time. For example:



Support for JSR-330

NoSQLUnit supports two annotations of JSR-330 aka Dependency Injection for Java. Concretely @Inject and @Named annotations.

During test execution you may need to access underlying class used to load and assert data to execute extra operations to backend. NoSQLUnit will inspect @Inject annotations of test fields, and try to set own driver to attribute. For example in case of MongoDb, com.mongodb.Mongo instance will be injected.


Note that in example we are setting this as second parameter to the Rule.

But if you are using more than one engine at same time, you need a way to distinguish each connection. For fixing this problem, you must use @Named annotation by putting the identifier given in configuration instance. For example:


Next release will support Neo4J and Cassandra. Stay in touch with the project and of course I am opened to any ideas that you think that could make NoSQLUnit better.


viernes, junio 08, 2012

Testing Abstract Classes (and Template Method Pattern in Particular)



Sick at heart and lonely, deep in dark despair. Thinking one thought only, where is she tell me where. (Heart Full of Soul - The Yardbirds).

From wikipedia "A template method defines the program skeleton of an algorithm. One or more of the algorithm steps can be overridden by subclasses to allow differing behaviors while ensuring that the overarching algorithm is still followed".

Typically this pattern is composed by two or more classes, one that is an abstract class providing template methods (non-abstract) that have calls to abstract methods implemented by one or more concrete subclasses.

Often template abstract class and concrete implementations reside in the same project, but depending on the scope of the project, these concrete objects will be implemented into another project.

In this post we are going to see how to test template method pattern when concrete classes are implemented on external project, or more general how to test abstract classes.

Let's see a simple example of template method pattern. Consider a class which is responsible of receiving a vector of integers and calculate the Euclidean norm. These integers could be received from multiple sources, and is left to each project to provide a way to obtain them.

The template class looks like:

Now another project could extend previous class and make an implementation of  abstract calculator by providing an implementation of read() method .

Developer that has written a concrete implementation will test only read() method, he can "trust" that developer of abstract class has tested non-abstract methods.

But how are we going to write unit tests over calculate method if class is abstract and an implementation of read() method is required?

The first approach could be creating a fake implementation:

This is not a bad approach, but has some disadvantages:
  • Test will be less readable, readers should know the existence of these fake classes and must know exactly what are they doing. 
  • As a test writer you will spend time in implementing fake classes, in this case it is simple, but your project could have more than one abstract class without implementation, or even with more than one abstract method.
  • Behaviour of fake classes are "hard-coded".
A better way is using Mockito to mock only abstract method meanwhile implementation of non-abstract methods are called.


Mockito simplifies the testing of abstract classes by calling real methods, and only stubbing abstract methods. See that in this case because we are calling real methods by default, instead of using the typical when() then() structure, doReturn schema must be used.

Of course this approach can be only used if your project does not contain a concrete implementation of algorithm or your project will be a part of a 3rd party library on another project. In the other cases the best way of attacking the problem is by testing the implemented class.

Download sourcecode

Music: http://www.youtube.com/watch?v=9O6eGOu27DA