execute Java code only in tests

1.7k Views Asked by At

There is a rule I would like to enforce in unit tests so that new code doesn't violate the rule. But I would like to just print warning out in production environment to allow production function regardless while I am cleaning it up.

I wonder if it's possible in Java to do the above in a clean way? Thanks!

3

There are 3 best solutions below

2
On BEST ANSWER

I can think of a few approaches:

  1. Use assertions
  2. Use a Java system property to only execute the code under test
  3. Use a static analysis tool like PMD (I don't think that fits your scenario)
  4. Use AOP (aspect oriented programming) and only instrument in testing locally

Most of these wouldn't give you the warning in production. But they wouldn't fail in production either.

What is best to do depends on what rule you are trying to check.

1
On

you can use assertion

Assertion:

Assertion is a statement in java. It can be used to test your assumptions about the program. While executing assertion, it is believed to be true. If it fails, JVM will throw an error named AssertionError. It is mainly used for testing purpose.

Advantage of Assertion:

It provides an effective way to detect and correct programming errors.

Syntax of using Assertion:

There are two ways to use assertion. First way is:

assert expression;  

and second way is:

assert expression1 : expression2;  

for more information see this link : http://javarevisited.blogspot.com/2012/01/what-is-assertion-in-java-java.html

0
On

You're defining two different behaviors of one component. If possible, define the component to respect those two modes, and test them.

class YourClass {
  private final boolean strictMode;

  YourClass() {
    this(false); // strict mode off by default
  }

  YourClass(boolean strictMode) {
    this.strictMode = strictMode;
  }

  void yourMethod(Object parameter) {
    if (parameter == null) {
      if (strictMode)
        throw new IllegalArgumentException();
      else
        System.err.println("YourClass.yourMethod parameter is null!")
    }
  }
}

class YourClassTest {
  @Test public void yourMethodNonStrictModeShouldAllowNull() {
    YourClass yourClass = new YourClass(false);
    yourClass.yourMethod(null);
  }

  @Test(exception=IllegalArgumentException.class)
  public void yourMethodStrictModeShouldThrowException() {
    YourClass yourClass = new YourClass(false);
    yourClass.yourMethod(null);
  }
}

By setting up the two different modes, and documenting and testing them, you give your tests the most flexibility to choose their intended level of strictness--and allows your fully-tested reusable component to be used in "strict mode" in production immediately when your cleanup is done.

(You may also choose to make the argument-taking constructor private, and make it accessible through a static factory method like YourClass.forUnitTesting().)