简体   繁体   English

JUnit测试断言

[英]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"; 我需要为以下代码构建Junit测试用例,并且尝试使其中一个测试测试assert s1 != null : "Violation of: s1 is not null"; , assert s2 != null : "Violation of: s2 is not null"; assert s2 != null : "Violation of: s2 is not null"; , and assert s1.length() >= 1 : "|s1| >= 1"; ,并assert s1.length() >= 1 : "|s1| >= 1"; statements gives an error when a null sequence is passed or when s1 's length is >= 1. 传递空序列或s1的长度> = 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. 我不会使用Java的断言来防止null引用,主要是因为可以(默认情况下)关闭该功能。 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. 相反,我将为此使用诸如Guava PreconditionsApache Commons Validate之类的前提条件库。 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. 除此之外,我还将使用“ NotNull”注释 (例如javax.annotation.Nonnull对方法参数进行注释 ,以便客户端代码将在现代IDE中获得编译时保护。

So, the method signature and the guard conditions would become like this (using Commons Validate): 因此,方法签名和保护条件将如下所示(使用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; 进行此更改之后,编写单元测试很简单,因为可以保证该方法会抛出一个NullPointerException ,从而使notNull检查失败,或者IllegalArgumentException ,从而使isTrue检查失败; 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: 用于检查传入的第一个参数不能为null的示例测试如下所示:

@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. 我完全同意另一个答案,但有一个细微的变化:如果您更喜欢添加对guava或apache之类的外部库的依赖的解决方案,那么Java自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. 注意:请勿混合使用两个参数-第一个参数将检查是否为null。

Beyond that: you should work on your naming skills. 除此之外:您应该提高命名技巧。 s1 and s2 ... mean nothing. s1和s2 ...毫无意义。 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; 甚至在阅读了5次之后; 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. 因此, 真正的答案是:您绝对想学习简洁的代码 (例如,通过阅读Robert Martin的书),以便在水平上进行改进。 Those asserts are just one aspect of many other problems in your source code ... 这些断言只是源代码中许多其他问题的一方面...

Use @Rule in your test class 在测试类中使用@Rule

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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