2013-08-27 19 views
1

我有一個控制器方法需要返回一個JSON映射,其中的一個項目是模板中的html。我正在使用的代碼,如在控制器中使用g.applyLayout中斷單元測試

map['html'] = g.applyLayout(name: 'layoutName', g.render(template: 'template', model: [...]) 
... 
render(map as JSON) 

而我在控制器單元測試調用此方法。然而,當我運行測試,我得到以下異常:

java.lang.IllegalStateException: Cannot return Sitemesh factory it has not been set! 
at org.springframework.util.Assert.state(Assert.java:384) 
at org.codehaus.groovy.grails.web.sitemesh.FactoryHolder.getFactory(FactoryHolder.java:39) 
at org.codehaus.groovy.grails.web.sitemesh.FactoryHolder$getFactory.call(Unknown Source) 
... 

如果我拿出g.applyLayout(),只是使用g.render()的測試運行。我究竟做錯了什麼?

更新

這裏是我的單元測試類

@TestFor(ContactsController) 
@Mock([Contact, User, Company]) 
class ContactsControllerTests { 
    @Test 
    void testSaveContact() { 
     defineBeans { 
      contactsManagerService(ContactsManagerService) 
     } 

     Company company = new Company(name: 'COMPANY 1') 
     company.save(validate: false) 
     Contact userContact = new Contact(name: 'user contact', email: '[email protected]') 
     Contact companyContact = new Contact(name: 'company contact', email: '[email protected]') 
     userContact.save(validate: false) 
     companyContact.save(validate: false) 
     new User(name: 'user 1', password: 'foo', contact: userContact, company: company).save(validate: false, deepValidate: false) 

     controller.params.name = '' 
     controller.params.email = '[email protected]' 
     controller.saveContact(userContact.id) 
     assertNotNull(response.json.errors) // Name cannot be empty 

     response.reset() 
     controller.params.name = 'Updated Name' 
     controller.params.email = '[email protected]' 
     controller.saveContact(userContact.id) 
     assertTrue(response.json.success) 

     Contact contact = Contact.read(userContact.id) 
     assertEquals('Updated Name', contact.name) 
     assertEquals('[email protected]', contact.email) 
    } 
} 
+1

你能分享你的完整單元測試課嗎? –

+0

更新了問題以包含單元測試。 – BillGoneMad

回答

2

在郵件列表中,我認爲你不能在單元測試中使用SiteMesh的相關標籤另一個話題眼看Jeff's response

可能的解決方案是:

  • 模擬你的HTML,聲稱生成的JSON是正確的;
  • 執行集成測試來驗證您的佈局和模板,因爲在集成中您可以訪問完整的環境。
+0

我可以嘲笑調用applyLayout()嗎? – BillGoneMad

+2

我弄清楚如何嘲笑調用我這樣做 '高清applyLayoutMock = mockFor(RenderTagLib,真) applyLayoutMock.demand.applyLayout {ATTRS,身體 - >迴歸 '應用佈局'} applyLayoutMock.demand.render {模板,模型 - >返回'模板呈現'} controller.metaClass.g = applyLayoutMock.createMock()'這似乎爲我工作。 – BillGoneMad

+1

如果您需要在沒有控制器的情況下模擬applyLayout(例如發送電子郵件的服務),則需要使用集成測試,並且需要對renderTagLib進行元類化(Sitemesh在集成測試中也不起作用)。 '高清renderTagLib = ApplicationContextHolder.getBean(RenderTagLib) renderTagLib.applyLayout = {ATTRS,身體 - > 回報體 }' –