nibiru

Time/Transition Unit testing extensions

License

License

GroupId

GroupId

io.teknek
ArtifactId

ArtifactId

tunit
Last Version

Last Version

0.0.0
Release Date

Release Date

Type

Type

jar
Description

Description

nibiru
Time/Transition Unit testing extensions
Source Code Management

Source Code Management

https://github.com/edwardcapriolo/tunit

Download tunit

How to add to project

<!-- https://jarcasting.com/artifacts/io.teknek/tunit/ -->
<dependency>
    <groupId>io.teknek</groupId>
    <artifactId>tunit</artifactId>
    <version>0.0.0</version>
</dependency>
// https://jarcasting.com/artifacts/io.teknek/tunit/
implementation 'io.teknek:tunit:0.0.0'
// https://jarcasting.com/artifacts/io.teknek/tunit/
implementation ("io.teknek:tunit:0.0.0")
'io.teknek:tunit:jar:0.0.0'
<dependency org="io.teknek" name="tunit" rev="0.0.0">
  <artifact name="tunit" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.teknek', module='tunit', version='0.0.0')
)
libraryDependencies += "io.teknek" % "tunit" % "0.0.0"
[io.teknek/tunit "0.0.0"]

Dependencies

compile (1)

Group / Artifact Type Version
junit : junit jar 4.11

Project Modules

There are no modules declared in this project.

tunit Build status

Time/Transition Unit testing extensions Motivation

At times complex async applications become hard to test. This is especially true for 3rd party applications, async applications, and background threads inside applications. TUnit (Time/Transition/Teknek Unit) is designed to help test these types of applications.

Usage

     TUnit.assertThat( new Callable<Integer>() {
      public Integer call() throws Exception {
        //something mutable
      }}).afterWaitingAtMost(2000, TimeUnit.MILLISECONDS).isEqualTo(40);

Motivation

To understand how TUnit might be useful, look at an application that has a class like the one below:

  class Changing implements Runnable {
    public volatile int x;
    public void run() {
      while (x < 10){
        x++;
        try {
          Thread.sleep(10);
        } catch (InterruptedException e) { }
      }
    }
  }

Because of the way threads work we can generally assume that the value of x will reach 10 in about 1 second. However, we do not know for sure when threads will get scheduled. Also what if we are not using a hardcoded sleep(10) ms? How might we test that?

  @Test
  public void aStatefulThingThatChanges() throws InterruptedException{
    //The Enemy
    Changing c = new Changing();
    new Thread(c).start();
    Thread.sleep(1000);
    Assert.assertEquals(10, c.x);
  }

Besides the code being ugly, the test suite runs as long as all the sleep statements. (If control everything you may not have to test like this, but that is usually not the case.)

The TUnit way

TUnit samples the changing object at 1 ms intervals. If the value of the item monitorsed ever equals the expected value the framework returns normally.

  @Test
  public void aStatefulThingThatChanges() throws InterruptedException{
    final Changing c = new Changing();
    new Thread(c).start();
    TUnit.assertThat( new Callable<Integer>() {
      public Integer call() throws Exception {
        return c.x;
      }}).afterWaitingAtMost(2000, TimeUnit.MILLISECONDS).isEqualTo(10);
  }

In the worst case scenario TUnit will wait no more than a specified amount of time (default 1 second).

  @Test
  public void aStatefulThingThatChangesButNeverPasss() throws InterruptedException{
    final Changing c = new Changing();
    new Thread(c).start();
    long start = System.currentTimeMillis();
    boolean threw = false;
    try { 
      TUnit.assertThat( new Callable<Integer>() {
      public Integer call() throws Exception {
        return c.x;
      }}).afterWaitingAtMost(2000, TimeUnit.MILLISECONDS).isEqualTo(40);
    } catch (ComparisonFailure ex){
      threw = true;
    }
    Assert.assertTrue(threw);
    Assert.assertTrue((System.currentTimeMillis() - start ) >= 2000 );
  }

Fluent style

There also is some hooks here for Fluent style stuff if you are interested.

public static class IsEqualTo implements Function1<Boolean,Integer>{
    private Integer n;
    public IsEqualTo(Integer n){
      this.n = n;
    }
    public Boolean function(Integer x) {
      return n.equals(x);
    }
  }
  
  public static IsEqualTo isEqualTo(int x){
    return new IsEqualTo(x);
  }
  
  @Test
  public void callableAssertIsFunc() throws InterruptedException{
    final Changing c = new Changing();
    new Thread(c).start();
    TUnit.assertThat( new Callable<Integer>() {
      public Integer call() throws Exception {
        return c.x;
      }}).is(isEqualTo(10));
  }

Maven

You can get this software from maven central.

  <dependency>
       <groupId>io.teknek</groupId>
      <artifactId>tunit</artifactId>
      <version>${pick_the_latest_version}</version>
  </dependency>

Versions

Version
0.0.0