简体   繁体   中英

JUnit testing assertions

I need to build Junit test cases for the following code and I am trying to have one of the tests test that the assert s1 != null : "Violation of: s1 is not null"; , assert s2 != null : "Violation of: s2 is not null"; , and assert s1.length() >= 1 : "|s1| >= 1"; statements gives an error when a null sequence is passed or when s1 's length is >= 1.

I don't know the exact way of going about doing this.

A couple forums suggested using "Try Catch" but I don't know exactly how that works.

Any help would be appreciated!

public static void itersmooth(Sequence<Integer> s1, Sequence<Integer> 
    s2){
  assert s1 != null : "Violation of: s1 is not null";
  assert s2 != null : "Violation of: s2 is not null";
  assert s1.length() >= 1 : "|s1| >= 1";
  s2.clear();
  if (s1.length() > 1){
    int inp1 = 1;
    for (int inp2 = 0; inp2 < (s1.length() - 1); inp2++){
      int valone = s1.remove(inp2);
      int valtwo = s1.remove(inp1 - 1);
      int valoneT = valone / 2;
      int valtwoT = valtwo / 2;

      int valtemp = valoneT + valtwoT;
      if ((valone % 2 != 0 || valtwo % 2 != 0) && (valone > 0 && valtwo > 0)) {
        valtemp++;
      }
      if ((valone % 2 != 0 || valtwo % 2 != 0) && (valone < 0 && valtwo < 0)){
        valtemp--;
      }
      s2.add(inp2, valtemp);
      s1.add(inp2, valone);
      s1.add(inp1, valtwo);
      inp1++;
    }
   }
 }

I would not use Java's assertions to guard against null references, mainly because that feature can be -- and by default is -- turned off. This can lead into really hard-to-spot bugs, if your test system has assertions enabled and your production system does not.

Instead, I would use a preconditions library such as Guava Preconditions or Apache Commons Validate for this purpose. In addition to this, I would annotate the method arguments with a "NotNull" annotation , eg javax.annotation.Nonnull , so that client code will get compile-time protection in a modern IDE.

So, the method signature and the guard conditions would become like this (using Commons Validate):

import org.apache.commons.lang3.Validate;
import javax.annotation.Nonnull;

//...
public static void itersmooth(@Nonnull Sequence<Integer> s1, 
                              @Nonnull Sequence<Integer> s2) {
       Validate.notNull(s1, "Violation of: s1 is not null");
       Validate.notNull(s2, "Violation of: s2 is not null");
       Validate.isTrue(s1.length() >= 1, "|s1| >= 1");

       // ...
   }

After this change, writing the unit test is simple, because the method is guaranteed to throw a NullPointerException for failing the notNull check, or an IllegalArgumentException , for failing the isTrue check; you don't need to worry about assertions being enabled or not.

An example test for checking that a passed-in first argument can't be null , would look like this:

@Test(expected=NullPointerException.class)
public void throwsWhenFirstSequenceIsNull() {
    MyClass.itersmooth(null, new Sequence<Integer>(1,2,3));
    Assert.fail("Null argument didn't cause an exception!");
}

I fully agree with the other answer, but one subtle variation: in case you prefer solutions that do not add dependencies on external libraries such as guava or apache, Java has a nice "built-in" thingy for that since Java7.

You can replace

assert s1 != null : "Violation of: s1 is not null";

with

Objects.requireNonNull(s1, "s1 must not be null");

Note: don't mix the two arguments - the first one is checked against null.

Beyond that: you should work on your naming skills. s1 and s2 ... mean nothing. They don't tell the reader anything about the purpose of those two variables. Same for most other names in that method. Try to use names that give information about the intended purpose of the thing behind the variable!

And beyond that: your whole code is extremely hard to read. It looks overly complex; and even after reading it 5 times; I still have no idea what it is supposed to do.

So the real answer here is: you absolutely want to learn about clean code (for example by reading the very book by Robert Martin) in order to improve on that level. Those asserts are just one aspect of many other problems in your source code ...

Use @Rule in your test class

@Rule
public ExpectedException exception = ExpectedException.none();   

public void testCase() {
    exception.expect(AssertionError.class);
    MyClass.itersmooth(null, new Sequence<Integer>(1,2,3));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM