Java 斯波克认为被测试类的内部枚举应该是Spec的属性
我有一个Java类,我正试图用Spock测试它。Java类包含一个内部枚举:Java 斯波克认为被测试类的内部枚举应该是Spec的属性,java,groovy,enums,spock,Java,Groovy,Enums,Spock,我有一个Java类,我正试图用Spock测试它。Java类包含一个内部枚举: import static java.util.Calendar.*; import java.util.*; public class FederalHolidays { public enum Observance { NEW_YEARS_DAY(JANUARY, 1), BIRTHDAY_OF_MARTIN_LUTHER_KING_JR(JANUARY, MONDAY,
import static java.util.Calendar.*;
import java.util.*;
public class FederalHolidays {
public enum Observance {
NEW_YEARS_DAY(JANUARY, 1),
BIRTHDAY_OF_MARTIN_LUTHER_KING_JR(JANUARY, MONDAY, 3),
WASHINGTONS_BIRTHDAY(FEBRUARY, MONDAY, 3),
MEMORIAL_DAY(MAY, MONDAY, -1),
INDEPENDENCE_DAY(JULY, 4),
LABOR_DAY(SEPTEMBER, MONDAY, 1),
COLUMBUS_DAY(OCTOBER, MONDAY, 2),
VETERANS_DAY(NOVEMBER, 11),
THANKSGIVING_DAY(NOVEMBER, THURSDAY, 4),
CHIRSTMAS_DAY(DECEMBER, 25);
private final int month;
private final int dayOfMonth;
private final int dayOfWeek;
private final int weekOfMonth;
private static final int NA = 0;
private Observance(int month, int dayOfMonth) {
this.month = month;
this.dayOfMonth = dayOfMonth;
this.dayOfWeek = NA;
this.weekOfMonth = NA;
}
private Observance(int month, int dayOfWeek, int weekOfMonth) {
this.month = month;
this.dayOfMonth = NA;
this.dayOfWeek = dayOfWeek;
this.weekOfMonth = weekOfMonth;
}
boolean isFixedDate() {
return dayOfMonth != NA;
}
}
public Date dateOf(Observance observance, int year) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"), Locale.ENGLISH);
cal.set(YEAR, year);
cal.set(MONTH, observance.month);
cal.clear(HOUR);
if (observance.isFixedDate()) {
cal.set(DAY_OF_MONTH, observance.dayOfMonth);
} else {
setNthDayOfWeek(cal, observance.dayOfWeek, observance.weekOfMonth);
}
adjustForWeekendsIfNecessary(cal);
return cal.getTime();
}
private void setNthDayOfWeek(Calendar cal, int dayOfWeek, int n) {
int week = 0;
int lastDay = cal.getActualMaximum(DAY_OF_MONTH);
int startDay = n > 0 ? 1 : lastDay;
int endDay = n > 0 ? lastDay : 1;
int incrementValue = n > 0 ? 1 : -1;
for (int day = startDay; day != endDay; day += incrementValue) {
cal.set(DAY_OF_MONTH, day);
if (cal.get(DAY_OF_WEEK) == dayOfWeek) {
week += incrementValue;
if (week == n) {
return;
}
}
}
}
private void adjustForWeekendsIfNecessary(Calendar cal) {
int dayOfWeek = cal.get(DAY_OF_WEEK);
cal.add(DAY_OF_MONTH, dayOfWeek == SATURDAY ? -1 : dayOfWeek == SUNDAY ? 1 : 0);
}
}
我的Spock测试规范如下所示:
class FederalHolidaysSpec extends Specification {
@Shared
def federalHolidays = new FederalHolidays()
def "holidays are correctly calculated"() {
expect:
federalHolidays.dateOf(observance, year).format('yyyy/MM/dd') == date
where:
observance | year | date
NEW_YEARS_DAY | 2011 | '2010/12/31'
BIRTHDAY_OF_MARTIN_LUTHER_KING_JR | 2011 | '2011/01/17'
WASHINGTONS_BIRTHDAY | 2011 | '2011/02/21'
MEMORIAL_DAY | 2011 | '2011/05/30'
INDEPENDENCE_DAY | 2011 | '2011/07/04'
LABOR_DAY | 2011 | '2011/09/05'
COLUMBUS_DAY | 2011 | '2011/10/10'
VETERANS_DAY | 2011 | '2011/11/11'
THANKSGIVING_DAY | 2011 | '2011/11/24'
CHIRSTMAS_DAY | 2011 | '2011/12/26'
}
}
当我运行Spock时,我得到10个测试错误,表中每行一个。每个错误都是相同的:
groovy.lang.MissingPropertyException: No such property: Observance for class: bdkosher.FederalHolidaysSpec
at bdkosher.FederalHolidaysSpec.$spock_initializeFields(FederalHolidaysSpec.groovy)
(我使用的是Spock 0.7-groovy-2.0、groovy all 2.2.2(非indy)和Java 1.7.045。)
为什么斯波克要在我的FederalHolidaysSpec类中查找名为Observation的属性?
我最初怀疑该问题与内部枚举/静态导入有关,但将我的Spock测试更改为使用完全限定的枚举值(例如bdkosher.FederalHolidays.Observation.CHRISTMAS_DAY)并没有什么区别
编辑:Java文件实现已更正,以便通过测试;测试文件中的输入错误已更正。请确保源代码和测试用例的软件包都正确。如果java类和测试类都在同一个包中,那么下面的方法对我来说是可行的
package bdkosher
import spock.lang.Shared
import spock.lang.Specification
//import bdkosher.FederalHolidays.Observance //Do not need
import static bdkosher.FederalHolidays.Observance.*
class FederalHolidaysSpec extends Specification { .. }
我在没有默认包名的情况下测试了
com.example
和Grails应用程序,尽管spock版本是相同的。在听说@elems'和@dmahaptro的成功后,我开始从我的项目结构中剥离一些东西,并减少POM中的依赖项
在完全删除了未使用的src/test/java
和src/main/groovy
目录后,我注意到IDE中的FederalHolidaysSpec.groovy
源文件恢复为旧版本(我不确定是否应该为此责备gmavenplus插件
或NetBeans——我怀疑是后者,因为我一直在使用mvn clean test
进行测试)。无论如何,这个旧版本包含一个额外的字段:
class FederalHolidaysSpec extends Specification {
def data = [(Observance.NEW_YEARS_DAY) : ['2011/12/31']]
此字段导致了测试错误。即使使用导入bdkosher.FederalHolidays.observation
,Groovy显然认为映射键是属性引用,而不是枚举
引用
无论如何,现在我可以修复打字错误和合法的测试失败。谢谢你的帮助。枚举是否也必须公开?是的,很好(我还没有尝试在其包之外使用API)。但是,即使我在上面添加了
public
修饰符,我仍然会得到相同的测试错误。@BDKosher我检查了你的代码。它对我很有效。我的设置:groovy 2.2.1,spock 0.7-groovy-2.0。除了多个输入错误和两个计算错误的日期外,所有这些都运行得很顺利。我不完全确定groovy是否支持导入嵌套类。看起来是这样的y、 使用FQN--def数据=[(gov.uspto.trademark.tmng.datetime.FederalHolidays.Observation.NEW_YEARS_DAY):['2011/12/31']
——不会导致任何错误。静态导入至少按照我的预期工作。导入gov.uspto.trademark.tmng.datetime.FederalHolidays
和(FederalHolidays.Observation.NEW_DAY)
可能也会起作用。是的,这是有效的。如果我导入gov.uspto.trademark.tmng.datetime.FederalHolidays.observation并定义一个字段def newYears=observation.NEW_YEARS\u DAY
,Groovy不会有任何抱怨。它只是在用作地图键时有问题。