Kodo is a framework that helps you creating specifications with the help of a fluent interface. Its main use if for testing but you can use for any purposes that requires the writing of a specification.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
.gitignore
LICENSE
README.md
changelog.md
pom.xml

README.md

Kodo

Kodo is a test framework that helps you defining specifications with the help of a fluent interface. The idea behind is to put some functional interfaces present in Java 8 together to provide a beautiful way to define specifications in pure Java code. Its main use if for testing but you can use for any purposes that requires the writing of a specification.

How To Build

Just make sure you have Maven and run the command maven package. To install kodo on your local maven repository, use the command maven install.

How to Use

Just put the really small kodo jar file on your classpath. You can also install kodo on your local repository and then define it on your pom or gradle build:

  • groupId: tools.devnull
  • artifactId: kodo

Kodo is also in Maven Central. Just use the above groupId and artifactId to declare the dependency.

Defining Specifications

To define a new specification, use the Spec class. It defines an entry point to the fluent interface:

Spec.given(someObject);

Spec.begin(); // for specifications without a target 

With the SpecDefinition interface returned, you can use a set of methods to describe behaviours:

Spec.given(someObject)
  .when(obj -> obj.foo())
  .expect(it(), obj -> obj.isValid());

This can be refactored to a more elegant code:

Spec.given(someObject)
  .when(itExecutes()) // an extracted method
  .expect(it(), to().be(valid())); // an extracted method

And messages may be supplied:

Spec.given(someObject)
  .when(itExecutes())
  .expect(it(), to().be(valid()), because("the process should not invalidate the object"));

You can also describe the whole Spec:

Spec.describe("My spec for testing my object")
  .given(myObject)
  .expect ...

Here is more examples:

Account accountA = new Account(500);
Account accountB = new Account(500);

Spec.begin()
  .expect(the(accountA), to().have(balanceOf(500)))
  .expect(the(accountB), to().have(balanceOf(500)))
  
  .when(() -> accountA.transfer(100).to(accountB))
  
  .expect(the(accountA), to().have(balanceOf(400)))
  .expect(the(accountB), to().have(balanceOf(600)))

  .expect(() -> accountA.transfer(1000).to(accountB), to().raise(InsufficientBalanceException.class))
  
  .expect(the(accountA), to().have(balanceOf(400)))
  .expect(the(accountB), to().have(balanceOf(600)));

// helper methods

  public static Predicate<Account> balanceOf(double value) {
    // Please don't use this comparisson in a real case scenario
    // this is just an example
    return account -> account.balance() == value;
  }
Spec.describe("A trader is alerted of status")
  .given(newStock("STK").withThresholdOf(15.0))

  .when(tradeAt(5.0))
  .expect(alert(), to().be("OFF"))

  .when(tradeAt(16.0))
  .expect(alert(), to().be("ON"));

// helper methods omitted

Also, take a look at the Expectation class. It contains a set of useful methods to help you write your awesome specifications!

How To Contribute

Fork it, fire an issue, spread the project, use the project... any help will be great! And, please, let me know if you're liking Kodo (or not).