testing grails
TRANSCRIPT
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Testing Grails Kenneth Kousen
@kenkousen [email protected]
Grails
• Full stack framework • Convention over configuration • DSLs written in Groovy
• Home page: http://grails.org • User guide: http://grails.org/doc/latest/
2
Philosophy
• Never trust a test you haven’t seen fail
3
Testing
• User guide • http://grails.org/doc/latest/guide/testing.html • Chapter 14 is latest version (2.4.3)
4
Generated tests
• Any create-* or generate-* command • Generates unit tests automatically
5
Unit vs Integration
• Standard project structure • test/unit • test/integration
6
Unit vs Integration
• Unit == No Grails infrastructure • Database == concurrent hash map in memory
• Integration uses Grails capabilities • Transactions • Dependency injection
7
Running tests
• Command line: • grails test-app
• Optional arguments for: • Specific package • Specific class • Specific artifacts (like all controllers)
8
Running tests
• Interactive console • Caching makes tests run much faster
grails> test-‐app –unit grails> open test-‐report
9
Spock
• Grails uses Spock testing framework by default • Grails 2.3+
10
Spock
• Easy to read and learn • Uses block structure • Has powerful data driven tests
11
Spock
• Write test method name as sentence • Add expect: or when:/then: blocks • Every statement in expect: or then: checked automatically
• Uses Groovy truth
12
@TestFor
• @TestFor annotation triggers “mixins” • For controllers and services, generates fields
13
@Mock
• Generates mock GORM method for domain classes
14
Testing Controllers
• @TestFor instantiates controller
15
Testing Controllers
• Testing render methods • Invoke method and use response object • Instance of GrailsMockHttpServletResponse • Has a getText() method
16
Testing Controllers
• Testing redirects • Invoke method and use response object • Has a getRedirectedUrl() method
17
Testing Controllers
• What if you need input parameters? • Use params map • Call set common properties
• max, sort, offset, …
• Can modify request, too request.method = ‘POST’
18
Testing Controllers
• Testing “return” methods • Grails adds map to request and forwards to GSP
• No need to test the forwarding (Grails infrastructure)
• Assign method call to a map and check keys/values
19
Testing Rendering
• If you render XML or JSON, • Use xml or json property of response object • Built with XmlSlurper or JsonSlurper
• Note: similar technique with request • Assign to request.xml or request.json
20
Testing Rendering
• Constants in ControllerUnitTestMixin • JSON_CONTENT_TYPE • TEXT_XML_CONTENT_TYPE • Many others
21
Testing Domain Objects
• Tests use ConcurrentHashMap for DB • Can test dynamic finders, criteria queries, …
22
Testing Constraints
• Test constraints by creating a valid object and breaking it • Use mockForConstraintsTests method
23
Spock
• Spock includes where: block • Anything that implements Iterable can be used
24
Expandos
• Expando class has no methods or attributes • Properties and methods can be added at runtime
Expando e = new Expando() e.myprop = 3 e.doStuff = { arg -‐> /* use arg somehow */ }
25
Mocks and Stubs
• Method mockFor • First arg is class being mocked • Second (optional) arg is “strict”
def geoMock = mockFor(GeocoderService, true) geoMock.demand.fillInLatLng { Castle c -‐> } controller.geocoderService = geoMock.createMock()
26
Integration Tests
• Uses Grails infrastructure • Real DB (from test environment) • Dependency injection • Transactions
27
Functional tests
• Nothing built into Grails • Done through plugins
28
Plugins
• Build test data • http://grails.org/plugin/build-test-data • Inspects constraints and generates valid instances
• Functional • Web driver functional: http://grails.org/plugin/webdriver • Canoo WebTest: http://grails.org/plugin/webtest • Selenium: http://grails.org/plugin/selenium • Geb: http://grails.org/plugin/geb
29