如何通过传递null参数来覆盖一个避免null参数的void方法?

时间:2015-10-01 22:48:01

标签: java unit-testing junit

我有这样的方法:

public class SomeService {
    public void sortByFieldX(List<MyClass> list) {
        if (list != null) {
            Collections.sort(list, new ComparatorOfMyClassThatUsesFieldX());
        }
    }
}

如何在sortByFieldX传递null参数的地方编写测试?

public class SomeServiceTest {
    @Test
    public void sortByFieldX() {
        List<MyClass> list = null;
        SomeService service = new SomeService();
        service.sortByFieldX(list);
        //assert what?
        //assertNull(list); is really stupid because Java is pass by value
    }
}

这个测试是否有效?我只是试图将这个测试作为一组测试的一部分来编写,以涵盖代码中的所有分支。

3 个答案:

答案 0 :(得分:4)

如果您传递null参数,则该方法不执行任何操作 - 它不会修改任何参数(因为它是null),它不会返回任何内容(由于它是void方法),它不会更新任何数据成员或抛出任何异常。

恕我直言,测试这样的情况有点毫无意义,但是如果你想要安全起见,那么唯一要测试的是null输入不会产生例外(特别是NullPointerException)。您提供的测试确实实现了这一目标。正如您在内联中所述,断言null实际上是null毫无意义。

编辑:
根据Spider the Spider在评论中的建议,使用ExpectedException规则可以更明确地显示此行为:

public class SomeServiceTest {
    @Rule
    public ExpectedException thrown= ExpectedException.none();

    /** Just makes sure no exception is thrown */
    @Test
    public void sortByFieldX() {
        List<MyClass> list = null;
        SomeService service = new SomeService();
        service.sortByFieldX(list);
    }
}

答案 1 :(得分:0)

您可以尝试添加此属性:

@Test(expected = NullPointerException.class)
public void sortByFieldX() {
        List<MyClass> list = null;
        SomeService service = new SomeService();
        service.sortByFieldX(list);
    }

答案 2 :(得分:0)

使用JUnit参数,您可以描述具有预期条件的测试套件(无论给定列表是否可为,可以为空):

package foo.bar;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import com.google.common.collect.Ordering;

/**
 * Use matrix of parameters and iterate over it to check all your conditions
 * with only one annonated method.
 *
 */
@RunWith(Parameterized.class)
public class SomeServiceTest {

    @Parameter
    public boolean isNull;

    @Parameter(value = 1)
    public boolean isSorted;

    @Parameter(value = 2)
    public List<MyClass> list;

    private static List<MyClass> listToSort = Arrays.asList( //
            new MyClass("D"), //
            new MyClass("B"), //
            new MyClass("A"), //
            new MyClass("C"));

    /**
     * Put your conditions here.
     */
    @Parameters
    public static Collection<Object[]> parameters() {
        return Arrays.asList(new Object[][] { //
                { true, true, null }, // test 1
                        { false, true, listToSort } // test 2
                // test n ...
                });
    }

    private Comparator<MyClass> comparator = new ComparatorOfMyClassThatUsesFieldX();

    @Test
    public void sortByFieldX() {
        // Given
        SomeService service = new SomeService();

        // When
        service.sortByFieldX(list);

        // Then
        assertEquals(isNull, list == null);
        if (Optional.ofNullable(list).isPresent()) {
            assertEquals(isSorted, Ordering.from(comparator).isOrdered(list));
        }
    }
}

比较器:

package foo.bar;

import java.util.Comparator;

public class ComparatorOfMyClassThatUsesFieldX implements Comparator<MyClass> {

    @Override
    public int compare(MyClass o1, MyClass o2) {
        if (o1.getFieldX() == o2.getFieldX()) {
            return 0;
        }
        if (o1.getFieldX() == null) {
            return -1;
        }
        if (o2.getFieldX() == null) {
            return 1;
        }
        return o1.getFieldX().compareTo(o2.getFieldX());
    }
}

如果您可以使用Java 8,我建议使用“单行”对列表进行排序:

private Comparator<MyClass> fieldComparator = Comparator.comparing(MyClass::getFieldX);

/**
 * Check null > parallelization > sort.
 * 
 * @param list
 *            Nullable list to sort.
 */
public void sortByFieldX(List<MyClass> list) {
    Optional.ofNullable(list).ifPresent(l -> l.parallelStream().sorted(fieldComparator));
}