Created
July 23, 2018 14:41
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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