【发布时间】:2015-03-11 17:42:16
【问题描述】:
我正在对我老板编写的一些代码进行单元测试。他在画一个空白,而我是 TDD 的新手,所以请和我一起集思广益。
我要测试的文件,EmailAssist 是此处未显示的服务的辅助类。如图所示,EmailAssist 应该引用其他几个服务,包括 sectionService。
class EmailAssist {
def sectionService
//condensed to relevant items
List<CommonsMultipartFile> attachments
Map emailMap =[:]
User user
Boolean valid
public EmailAssist(){
valid = false
}
public EmailAssist(GrailsParameterMap params, User user){
//irrelevant code here involving snipped items
this.setSections(params.list('sections'))
//series of other similar calls which are also delivering an NPE
}
//third constructor using third parameter, called in example but functionally
//similar to above constructor.
//definition of errant function
void setSections(List sections) {
emailMap.sections = sectionService.getEmailsInSectionList(sections, user)
}
正在调用的SectionService部分如下。
Set<String> getEmailsInSectionList(List<String> sections, User user) {
if(sections && user){
//code to call DB and update list
}
else{
[]
}
我的测试没有提供一个部分,所以这应该返回一个空列表,特别是因为我什至无法在单元测试中访问数据库。
单元测试如下。这是使用 mockFor,因为 spock 的模拟功能似乎不是我所需要的。
@TestMixin(GrailsUnitTestMixin)
class EmailAssistSpec extends Specification {
@Shared
GrailsParameterMap params
@Shared
GrailsMockHttpServletRequest request = new GrailsMockHttpServletRequest()
@Shared
User user
@Shared
def sectionService
def setup() {
user = new User(id: 1, firstName: "1", lastName: "1", username: "1", email: "1@1.com")
def sectionServiceMock = mockFor(SectionService)
sectionServiceMock.demand.getEmailsInSectionList() {
[]
}
sectionService = sectionServiceMock.createMock()
}
def cleanup(){
}
void testGetFiles(){
when:
//bunch of code to populate request
params = newGrailsParameterMap([:], request)
EmailAssist assist = new EmailAssist(params, request, user)
//Above constructor call generates NPE
具体的 NPE 如下: java.lang.NullPointerException:无法在空对象上调用方法 getEmailsInSectionList() 在
emailMap.sections = sectionService.getEmailsInSectionList(sections, user)
这是我的 setSections 函数的主体,适合那些在家玩的人。 NPE 堆栈源自我的测试文件中的构造函数调用。我也尝试过使用 spock 风格的模拟,但该服务仍然被认为是空的。最糟糕的是,构造函数甚至不是这个测试应该测试的,它只是拒绝传递它,结果导致测试无法运行。
如果我可以提供更多细节来澄清事情,请告诉我,谢谢!
编辑:我将构造函数中的设置器短路以完成测试,但这在测试覆盖率中留下了一些明显的漏洞,我无法弄清楚如何修复。也许我的嘲笑位于错误的地方? Spock 的模拟文档对于复杂的函数不是很方便。
【问题讨论】:
标签: unit-testing grails groovy mocking spock