Moxy core

Fluent API mocking/spying framework for Java.

License

License

GroupId

GroupId

com.roscopeco.moxy
ArtifactId

ArtifactId

moxy-core
Last Version

Last Version

0.94.0
Release Date

Release Date

Type

Type

jar
Description

Description

Moxy core
Fluent API mocking/spying framework for Java.

Download moxy-core

How to add to project

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

Dependencies

compile (7)

Group / Artifact Type Version
org.ow2.asm : asm jar 7.1
org.ow2.asm : asm-commons jar 7.1
org.ow2.asm : asm-tree jar 7.1
org.ow2.asm : asm-util jar 7.1
net.bytebuddy : byte-buddy-agent jar 1.8.12
org.opentest4j : opentest4j jar 1.0.0
org.apache.commons : commons-lang3 jar 3.7

test (5)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-api jar 5.1.1
org.junit.jupiter : junit-jupiter-engine jar 5.1.1
org.junit.platform : junit-platform-runner jar 1.1.1
org.assertj : assertj-core jar 3.10.0
nl.jqno.equalsverifier : equalsverifier jar 3.1.9

Project Modules

There are no modules declared in this project.

Build Status Quality Gate Bugs Code Smells Coverage Lines of Code

Maintainability Rating Reliability Rating Security Rating Technical Debt

Moxy

Lean-and-mean mocking framework for Java with a fluent API.

See also Javadoc.

What is this?

Moxy is a fairly lightweight yet surprisingly powerful and refeshingly non-opinionated mock/spy framework for use in testing Java code. It has a fluent, IDE-friendly stubbing and verification API, runs on Java 11+, and includes out-of-the-box support for allegedly-evil things such as mocking finals and statics. It knows its place as a tool - when it's right for the job, it's just what you need, but equally it will let you do all the wrong things really, really well if that's your cup of tea.

If it helps, think of it like a hammer. Or an elephant gun. Or something...

How do I use it?

Note for use with modern Java versions

If using the DefaultClassGenerationStrategy (the obviously-named default), you'll need to add the following to the JVM arguments when running your tests in your IDE:

--add-opens java.base/java.lang=com.roscopeco.moxy.core

(For example, in IntelliJ this can be added to the VM Arguments in your run configuration).

General usage

There's full documentation on the wiki, which took quite a while to write, and which I try to keep as up-to-date as possible.

But in the spirit of getting you started, here's a SSCCE we made earlier, paraphrased somewhat from Moxy's own tests:

import static com.roscopeco.moxy.Moxy.*;
import static com.roscopeco.moxy.matchers.Matchers.*;
import static org.assertj.core.api.Assertions.*;

import org.junit.jupiter.api.Test;

class TestClass {
  public String sayHelloTo(final String who) {
    return "Hello, " + who;
  }

  public String hasTwoArgs(final String arg1, final int arg2) {
    return "" + arg1 + arg2;
  }
}

final class HardToMockClass {
  public static String staticSayHello(final String who) {
    return "Hello, " + who;
  }

  public final String finalSayHello(final String who) {
    return "Goodbye, " + who;
  }
}

public class ReadmeSSCCE {
  @Test
  public void testClassMockVerifying() {
    mockClasses(HardToMockClass.class);

    when(() -> HardToMockClass.staticSayHello("Bill")).thenCallRealMethod();
    when(() -> HardToMockClass.staticSayHello("Steve")).thenReturn("Hi there, Steve!");

    assertThat(HardToMockClass.staticSayHello("Bill")).isEqualTo("Hello, Bill");
    assertThat(HardToMockClass.staticSayHello("Steve")).isEqualTo("Hi there, Steve!");

    final HardToMockClass mock = new HardToMockClass();

    when(() -> mock.finalSayHello("Jim")).thenAnswer(args -> "He's dead, Jim");

    assertThat(mock.finalSayHello("Jim")).isEqualTo("He's dead, Jim");

    assertMock(() -> HardToMockClass.staticSayHello(any())).wasCalledTwice();
    assertMock(() -> mock.finalSayHello(any())).wasCalledOnce();
  }

  @Test
  public void testClassicMockVerifying() {
    final TestClass mock = mock(TestClass.class);

    mock.sayHelloTo("Bill");
    mock.hasTwoArgs("one", 1);

    assertMocks(() -> {
      mock.sayHelloTo("Steve");
      mock.hasTwoArgs("two", 2);
    })
        .wereNotCalled();

    assertMocks(() -> {
      mock.sayHelloTo("Bill");
      mock.hasTwoArgs("one", 1);
    })
        .wereAllCalledOnce()
        .inThatOrder();
  }
}

This barely scratches the surface though, so be sure to check out that lovingly-crafted documentation.

Requirements

Compile/runtime:
  • Java (11+).
  • ASM 7.0 (base, -tree, -commons and -util)
  • Apache commons-lang3 3.7
  • opentest4j 1.0.0
For building/testing
  • Maven 3 (tested with 3.5.3)
  • Junit 5
  • AssertJ 3.8

Getting the code

Maven

Moxy releases are available in Maven Central. You can pull it in with the following dependency in your POM:

<dependency>
	<groupId>com.roscopeco.moxy</groupId>
	<artifactId>moxy-core</artifactId>
	<version>0.94.0</version>
</dependency>

If you want to use the JUnit 5 extension to ensure your mocks are reset prior to each test, include the following dependency:

<dependency>
	<groupId>com.roscopeco.moxy</groupId>
	<artifactId>moxy-junit5</artifactId>
	<version>0.94.0</version>
</dependency>

and if you're interesting in creating your mocks with Mockito-style annotations, include this:

<dependency>
	<groupId>com.roscopeco.moxy</groupId>
	<artifactId>moxy-annotations</artifactId>
	<version>0.94.0</version>
</dependency>

Development snapshots are sometimes made available in Maven via some extra configuration. See this wiki page for more information.

Note that, depending on where we are in the release cycle, it is possible for the latest snapshot to be behind the current release. Check version numbers before using a snapshot.

Gradle

Something like the following should have you set up:

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'com.roscopeco.moxy:moxy-core:0.94.0'
}
Clone from Git

You can clone the latest code (or any release using the appropriate tag) directly from GitHub, and just set it up as a dependent project/module/whatever in your IDE, or make sure it's somewhere on your classpath, and you should be good to go.

The project is built with Maven, so just running mvn package will grab the dependencies and build you a .jar file in the target/ directory.

If you do mvn install you'll be able to reference it from your other Maven projects locally in the usual way.

You can generate a bit of Javadoc with mvn javadoc:javadoc, which generates the docs in target/apidocs. The Javadoc for the current release can always be found at https://roscopeco.github.io/moxy/ .

The legal bit

Moxy is copyright (c)2018-2019 Ross Bamford (and contributors)

This is open-source software under the MIT license. See LICENSE for details.

Versions

Version
0.94.0
0.92.2
0.92.1
0.92
0.90.1
0.90.0
0.88.1
0.88.0