0

I'm writing controller unit tests and I'd like to test json result when creation fails.

How can I register VndErrorJsonRenderer in unit test ? I tried simply defineBeans in setup() but it doesn't work :(

import com.vividsolutions.jts.geom.Coordinate
import grails.transaction.Transactional
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsParameterMap

import static org.springframework.http.HttpStatus.CREATED
import static org.springframework.http.HttpStatus.NO_CONTENT

@Transactional(readOnly = true)
class UserController {

    static namespace = "v1"

    static allowedMethods = [profile: 'GET', create: "POST", update: "PUT", delete: "DELETE"]
    static responseFormats = ['json', 'vnd.error+json']

    def springSecurityService

    def geometryFactory


    /**
     * Saves a resource
     */
    @Transactional
    def create() {
        User instance = createResource(params)

        instance.validate()
        if (instance.hasErrors()) {
            respond instance.errors, view: 'create' // STATUS CODE 422
            return
        }

        instance.save flush: true

        respond instance, [status: CREATED]
    }

    protected User createResource(GrailsParameterMap params) {
        Double x = params.double("location.x", 0)
        Double y = params.double("location.y", 0)
        User user = new User()
        bindData(user, params, [include: ['username', 'password', 'profile.*']])
        if (x > 0 && y > 0)
            user.location = geometryFactory.createPoint(new Coordinate(x, y))
        else
            user.location = null
        user.roles = []
        user.roles.add(Role.findByAuthority(Role.ROLE_USER))
        return user
    }



}

And my test :

@Before
void setup() {
    defineBeans {
        vndJsonErrorRenderer(VndErrorJsonRenderer)
    }
}
void "Test the create action with a non unique username"() {
        User.metaClass.encodePassword = {
            "aaa"
        }
        // Create first user
        assertNotNull getValidUser().save(flush: true)

        when: "The create action is executed with a username already used"
        def user = getValidUser()
        controller.request.addHeader("Accept", "application/vnd.error+json,application/json")
        controller.request.contentType = "application/json"
        controller.request.content = JsonMapperUtil.mapAsJson(user)?.getBytes()
        controller.create()

        then: "The response status is UNPROCESSABLE_ENTITY and the username unique error is returned"
        println response.text
        response.status == UNPROCESSABLE_ENTITY.value
        def json = JSON.parse(response.text)
        assertNull "VND format not returned", json.errors
    }

I'm using grails 2.3.6 with restful controller.

Thanks

persa
  • 37
  • 6
  • Duplicate [question](http://stackoverflow.com/questions/21996568/using-custom-renderer-in-grails-unit-testing-and-in-general-on-json-content-ty/21997058#21997058)? – dmahapatro Mar 07 '14 at 16:09
  • @dmahapatro It looks like but the proposed solution doesn't work :( I use spock for tests (extends Specification) but if I define vndJsonErrorRenderer member in test class it does not instanciate it. Even if I instanciate it manually, it does not work. Ressources.groovy is not loaded in unit tests. And as I use spock, defineBeans does not work. Is there a factory that look for renderers and register them on app loading ? – persa Mar 07 '14 at 16:45

1 Answers1

0

In the case you are showing where you depend on respond it would be best to test this more as an integration test so all components that may interact with respond are all wired for you.

In a unit test for what ever beans are needed in the class under test I find it easiest to directly set them on the class under test.

Jeff Beck
  • 3,944
  • 3
  • 28
  • 45
  • Unfortunatly the vndJsonErrorRenderer bean is not a member of my controller. It's just defined in resources.groovy – persa Mar 10 '14 at 08:31
  • Updated answer sorry I think you need to do an integration test – Jeff Beck Mar 10 '14 at 15:52
  • Ok thanks.I will take a look at functional-test plugin. It should be easier to test restful apis with this. – persa Mar 10 '14 at 16:59