Maker<Problem> defaultProblem = a(Problem,
with(className, "BinaryCode"), with(methodName, "decode"), with(returnType, "String[]"),
with(paramTypes, new String[]{"String"}), with(paramNames, new String[]{"message"}),
with(testCases, new TestCase[] { make(defaultTestCase) }));
Problem problem = make(defaultProblem);
Problem problemCopy = make(defaultProblem);
Problem problemWithDifferentClassName = make(defaultProblem.but(with(className, "Lottery")));
Problem problemWithDifferentReturnType = make(defaultProblem.but(with(returnType, "float")));
Problem problemWithDifferentMethodName = make(defaultProblem.but(with(methodName, "calculate")));
Problem problemWithDifferentParamType = make(defaultProblem.but(with(paramTypes, new String[]{"int"})));
Problem problemWithDifferentParamName = make(defaultProblem.but(with(paramNames, new String[]{"m"})));
Problem problemWithDifferentTestCase = make(defaultProblem.but(
with(testCases, new TestCase[] { make(defaultTestCase.but(with(output, "2"))) })));
assertTrue("problems with the same fields should be equal", problem.equals(problemCopy));
assertTrue("hash codes of problems with the same fields should be equal", problem.hashCode() == problemCopy.hashCode());
assertFalse("problems with different class names should not be equal", problem.equals(problemWithDifferentClassName));