Skip to content

Instantly share code, notes, and snippets.

@cyriux
Created July 23, 2018 14:41
Show Gist options
  • Save cyriux/631253bd7d6b01a936239af1b6ba596a to your computer and use it in GitHub Desktop.
Save cyriux/631253bd7d6b01a936239af1b6ba596a to your computer and use it in GitHub Desktop.
Testing the properties of a Monoid with Property-based Testing in Java with JUnit-Quickcheck
package pbt;
import static org.junit.Assert.assertEquals;
import static pbt.MonoidTest.Balance.ERROR;
import static pbt.MonoidTest.Balance.ZERO;
import org.junit.runner.RunWith;
import com.pholser.junit.quickcheck.From;
import com.pholser.junit.quickcheck.Property;
import com.pholser.junit.quickcheck.generator.Ctor;
import com.pholser.junit.quickcheck.runner.JUnitQuickcheck;
@RunWith(JUnitQuickcheck.class)
public class MonoidTest {
@Property
public void neutralElement(@From(Ctor.class) Balance a) {
assertEquals(a.add(ZERO), a);
assertEquals(ZERO.add(a), a);
}
@Property
public void associativity(@From(Ctor.class) Balance a, @From(Ctor.class) Balance b, @From(Ctor.class) Balance c) {
assertEquals(a.add(b).add(c), a.add(b.add(c)));
}
// This particular monoid happens to be commutative
@Property
public void commutativity(@From(Ctor.class) Balance a, @From(Ctor.class) Balance b) {
assertEquals(a.add(b), b.add(a));
}
@Property
public void errorIsAbsorbingElement(@From(Ctor.class) Balance a) {
assertEquals(a.add(ERROR), ERROR);
assertEquals(ERROR.add(a), ERROR);
}
public static class Balance {
// the nominal value of the balance
private final int balance;
// marks this instance as an error
private final boolean error;
// neutral element
public final static Balance ZERO = new Balance(0);
// error element, is absorbing element
public final static Balance ERROR = new Balance(0, true);
public Balance(int balance) {
this(balance, false);
}
private Balance(int balance, boolean error) {
this.balance = balance;
this.error = error;
}
public boolean isError() {
return error;
}
public Balance add(Balance other) {
return error ? ERROR : other.error ? ERROR : new Balance(balance + other.balance);
}
@Override
public int hashCode() {
return (int) (31 ^ balance);
}
@Override
public boolean equals(Object o) {
Balance other = (Balance) o;
return balance == other.balance && error == other.error;
}
@Override
public String toString() {
return error ? "ERROR" : balance + "";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment