io.scalecube:scalecube-fixtures-tck-flow

ScaleCube is a lightweight decentralized cluster membership, failure detection, messaging and gossip protocol library for the Java VM.

License

License

GroupId

GroupId

io.scalecube
ArtifactId

ArtifactId

scalecube-fixtures-tck-flow
Last Version

Last Version

0.0.13
Release Date

Release Date

Type

Type

jar
Description

Description

ScaleCube is a lightweight decentralized cluster membership, failure detection, messaging and gossip protocol library for the Java VM.

Download scalecube-fixtures-tck-flow

How to add to project

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

Dependencies

compile (1)

Group / Artifact Type Version
io.scalecube : scalecube-test-utils jar 0.0.13

test (1)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-engine jar 5.4.2

Project Modules

There are no modules declared in this project.

Test utilities for Scalecube

Codacy Badge

Codacy Badge

As a test developer I want to have the ability to test some components in multiple types of environment.

Some environments would be with mocks. Some would mock only data-layers and create all components in this test JVM. Some environments would be as docker containers plus real machines hybrid. You name it!!!

But as the tests writer - I truly don't care.

So what's the plan?

Let's split environments and tests

let's say we have two interfaces:

package io.scalecube.test.fixtures;

@FunctionalInterface
public interface EchoService {
  String echo(String s);
}

And

@FunctionalInterface
public interface PalindromeService {
  boolean palindrome(String s);
}

Both of them are in the system under test.

The test

package io.scalecube.test.fixtures;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(Fixtures.class)
@WithFixture(SlowServiceFixture.class)
@WithFixture(FasterServiceFixture.class)
public class BaseTest {

  @TestTemplate
  public void test(EchoService echoService, PalindromeService palindromeService) {
    System.out.println("------ test -----");
    assertTrue(palindromeService.palindrome(echoService.echo("CABAC")));
    assertFalse(palindromeService.palindrome(echoService.echo("TEST")));
  }
}

This test is testing EchoService and PalindromeService. As you can see, these are given to the test code as plain parameters to the test method as interfaces. So where are the concrete objects? in the Fixtures: here is an example of a tested system in-memory SlowServiceFixture and FasterServiceFixture:

The fixtures

public class SlowServiceFixture implements Fixture {

  EchoService echoService;
  PalindromeService palindromeService;

  @Override
  public void setUp() {
    echoService = s -> new StringBuilder(s).reverse().reverse().reverse().reverse().toString();
    this.palindromeService = s -> new StringBuilder(s).reverse().reverse().reverse().reverse().reverse().toString().equals(s);
    System.out.println("service.init");
  }

  @Override
  public <T> T proxyFor(Class<? extends T> aClass) {
    if (aClass.isAssignableFrom(EchoService.class)) {
      return aClass.cast(echoService);
    }
    if (aClass.isAssignableFrom(PalindromeService.class)) {
      return aClass.cast(palindromeService);
    } else {
      return null;
    }
  }

  @Override
  public void tearDown() {
    System.out.println("echo service kill");
  }
}

And...

public class FasterServiceFixture implements Fixture {

  EchoService echoService;
  PalindromeService palindromeService;

  @Override
  public void setUp() {
    echoService = s -> new StringBuilder(s).toString();
    this.palindromeService = s -> new StringBuilder(s).reverse().toString().equals(s);
    System.out.println("service.init");
  }

  @Override
  public <T> T proxyFor(Class<? extends T> aClass) {
    if (aClass.isAssignableFrom(EchoService.class)) {
      return aClass.cast(echoService);
    }
    if (aClass.isAssignableFrom(PalindromeService.class)) {
      return aClass.cast(palindromeService);
    } else {
      return null;
    }
  }

  @Override
  public void tearDown() {
    System.out.println("echo service kill");
  }
}

Obviously, there are more options, like:

public class DockerfileFixture implements Fixture {

  private EchoService echoService;
  private PalindromeService palindromeService;
  GenericContainer genericContainer;

  @Override
  public void setUp() {

    ImageFromDockerfile imageFromDockerfile =
        new ImageFromDockerfile()
            .withDockerfileFromBuilder(
                builder -> builder.from("ubuntu").entryPoint("sleep infinity").build());
    genericContainer = new GenericContainer<>(imageFromDockerfile);
    genericContainer.start();
    echoService =
        s -> {
          try {
            return genericContainer.execInContainer("echo", s).getStdout().trim();
          } catch (UnsupportedOperationException
              | IOException
              | InterruptedException ignoredException) {
            return ignoredException.getMessage();
          }
        };

    palindromeService =
        s -> {
          try {
            StringBuilder cmd =
                new StringBuilder("if [ \"`echo ")
                    .append(s)
                    .append(" | rev`\" = \"")
                    .append(s)
                    .append("\" ];")
                    .append(" then echo true;")
                    .append(" else echo false;")
                    .append("fi");

            ExecResult execResult = genericContainer.execInContainer("/bin/bash","-c", cmd.toString());
            return Boolean.valueOf(execResult.getStdout().trim());
          } catch (UnsupportedOperationException
              | IOException
              | InterruptedException ignoredException) {
            ignoredException.printStackTrace();
            return false;
          }
        };
  }

  @Override
  public <T> T proxyFor(Class<? extends T> clasz) {
    if (EchoService.class.isAssignableFrom(clasz)) {
      return clasz.cast(echoService);
    } else if (PalindromeService.class.isAssignableFrom(clasz)) {
      return clasz.cast(palindromeService);
    }
    return null;
  }

  @Override
  public void tearDown() {
    genericContainer.close();
  }
}

which will do the same in dockers!

io.scalecube

SCΛLΞ CUBΞ

⚛ High-Speed ⚛ Cloud-Native ⚛ Reactive Microservices ⚛

Versions

Version
0.0.13
0.0.11
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4