我有一个班级,他们唯一的任务就是选择List<Object>
并返回已排序的List<Object>
。例如,类中的sort方法使用一个过程,该过程将对象随机放置在列表中。
尝试执行:为该排序方法(或类)编写测试,如果排序实际上只是随机的,则必须失败。这意味着我需要找到List<Object>
命令来测试我假设。
要测试的代码
class RootLoggerFirstSorter {
List<LoggerConfig> sort(List<LoggerConfig> unSortedList) {
List<LoggerConfig> levelSortedList = new ArrayList<>(unSortedList);
Collections.sort(levelSortedList, new Comparator<LoggerConfig>() {
@Override
public int compare(LoggerConfig o1, LoggerConfig o2) {
if (o1.getLevel().intLevel() == o2.getLevel().intLevel()) {
return 0;
} else if (o1.getLevel().intLevel() < o2.getLevel().intLevel()) {
return 1;
} else {
return -1;
}
}}
);
LinkedList<LoggerConfig> sortedList = new LinkedList<LoggerConfig>();
for(Iterator<LoggerConfig> i = levelSortedList.iterator(); i.hasNext();) {
LoggerConfig cfg = i.next();
addNextLoggerConfig(cfg, sortedList);
}
return sortedList;
}
private void addNextLoggerConfig(LoggerConfig cfg, LinkedList<LoggerConfig> sortedList) {
if(cfg.getName() == null || cfg.getName().isEmpty()) {
sortedList.addFirst(cfg);
} else {
sortedList.addLast(cfg);
}
}
}
尝试
.....
expect(item1.getLevel()).andStubReturn(Level.DEBUG);
expect(item2.getLevel()).andStubReturn(Level.ERROR);
expect(item3.getLevel()).andStubReturn(Level.INFO);
.....
//Ignore the pre req for test setup
@Test
public void testSort() {
List<LoggerConfig> unsortedList = makeUnsortedList();
EasyMock.replay(item1,item2,item3);
List<LoggerConfig> sortedList = tested.sort(unsortedList);
assertThat("First item on the list is ERROR level: ", sortedList.get(0).getLevel(), is(Level.ERROR) );
assertTrue(sortedList.get(1).getLevel().equals(Level.INFO) || sortedList.get(1).getLevel().equals(Level.INFO));
assertTrue(sortedList.get(2).getLevel().equals(Level.DEBUG) || sortedList.get(2).getLevel().equals(Level.DEBUG));
}
但是这个测试总是会通过,因为如果仅查看索引1和2,索引0将始终包含具有空名称的LoggerConfig [设置以这种方式完成])。所以我想我应该单独测试比较方法吗?如果是,怎么做?
问题问题是我需要使用特定的Object属性测试sort方法,该属性是LoggerConfig
对象的级别。因此,测试必须检查List
顺序。
答案 0 :(得分:2)
这里有许多不同的方面:
A)是通过您在自己的答案中输入的代码实现的。或者确切地说:您仅需要一个测试用例,您可以对其进行排序检查预期结果;在为您的方法提供特定的测试输入之后。
B)是通过编写测试代码来实现的,该代码只是检查compareTo()返回不同输入的预期结果
最后,这是关于正确将您的逻辑分解为类。当然你可以将比较器声明为匿名内部类;并只验证sort方法返回预期的结果。
但是当你制作比较器时,在某个地方说一个内部类,你可以只为比较器功能编写单元测试。
最后:您的测试用例不表示您声明的目标:如果排序实际上只是随机,则必须失败。你看,如果sort()的结果是 random ,它可以随机给你一个正确的结果。含义:您不能指望单个测试来验证“可能的随机行为”。您必须使用大量不同的数据运行许多测试,并验证它们的全部是否通过;实现某种置信度,sort()不是纯随机的。
但是如上所述:你没有排序。您正在调用内置排序方法,不需要进行测试。
答案 1 :(得分:0)
不,你不应该。如果您稍后尝试重构排序方法,则测试可能会失败。您实际上是在尝试断言可能已完成排序。比较方法只是一个实现细节。您可能不会使用比较方法将来对列表进行排序。我应该只对比较方法进行单元测试吗?
当然,您也不需要测试内置排序方法,因为您实际上是在测试自定义排序方法。此排序方法中的任何内容都是实现细节,包括您调用的list.sort方法。在编写测试时,你应假装不知道它。
除此之外,您的sort方法还包含一些与内置排序方法无关的逻辑。
答案 2 :(得分:0)
我认为List<ConfigLogger>
跟item1["", ERROR], item2["com.fwk.foo", DEBUG], item3["com.fwk.core.baa", INFO]
之类的东西有关。因此,在这种情况下,我需要检查如果item3在位置1并且item2在列表中的位置3,则实现正确排序。所以我需要的测试如下:
@Test
public void testSort() {
List<LoggerConfig> unsortedList = makeUnsortedList();
EasyMock.replay(item1,item2,item3);
List<LoggerConfig> sortedList = tested.sort(unsortedList);
assertFalse(unsortedList.equals(sortedList));
assertTrue(sortedList.get(0).getName().isEmpty());
LoggerConfig cfg1 = sortedList.get(1);
LoggerConfig cfg2 = sortedList.get(2);
assertThat(cfg1.getLevel(), is(Level.DEBUG));
assertThat(cfg2.getLevel(), is(Level.INFO));
}
所以我从列表中访问该项目并比较它们是否与预期相同。