let’s groove with groovy

Post on 06-Dec-2014

3.855 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Java 6 bietet Scripting-Support out-of-the-Box. Mit Groovy existiert eine Scriptsprache, die sich eng an Java anlehnt und reichlich Gebrauch der Java-Infrastruktur macht. Grund genug Groovy einmal genauer unter die Lupe zu nehmen. Thorsten Kamann wird in seinem Vortrag die Grundkonzepte vorstellen. Anhand von einfachen Beispielen zeigt er die Mächtigkeit und Eleganz dieser Scriptsprache auf. Im 2. Teil des Vortrags geht er auf erweiterte Konzepte und Komponenten von Groovy ein. Themen werden u.a. sein: * Installation * Syntax - Schleifen * Bedingungen * Closures * GStrings * Regex * GroovyBeans * GroovyBuilder o XML o HTML o ANT o Swing o SWT * Unit-Tests (jUnit, Stubs, Mocks, Code-Coverage,…) * Weitere Groovy-Komponenten * Grails

TRANSCRIPT

Thorsten Kamann ● thorsten.kamann@itemis.de 11

Thorsten Kamann ● thorsten.kamann@itemis.de 22

Agenda

Was ist Groovy?

Getting started

Syntax

GroovyBeans

XML-Processing

Groovy Builder

Testing

Grails

Groovy Module

IDE-Support

Links

Thorsten Kamann ● thorsten.kamann@itemis.de 33

• Skriptsprachen sind Programmiersprachen, die vor allem für kleine, überschaubare Programmieraufgaben gedacht sind

• Kein Deklarationszwang für Variablen

• Automatische Speicherverwaltung

• Werden in der Regel ohne getrennte Übersetzungsphase ausgeführt (d. h. sie werden „interpretiert“)

Was ist Scripting?

Thorsten Kamann ● thorsten.kamann@itemis.de 44

• Eine dynamische Sprache

• Inspiriert von Ruby, Python, Smalltalk

• Entwickelt für die Java-Plattform

– Um sie Java-Entwicklern zugänglich zu machen

– Um möglichst viel der Java-Syntax wieder verwenden zu können

– Um eine einfache Anbindung zu Enterprise-Systemen anzubieten

Was ist Groovy?

Thorsten Kamann ● thorsten.kamann@itemis.de 55

Thorsten Kamann ● thorsten.kamann@itemis.de 66

• Download des aktuellen Release von http://groovy.codehaus.org

• Entpacken des Archivs

• Setzen der Umgebungsvariable GROOVY_HOME

• Hinzufügen von %GROOVY_HOME%\bin zur PATH-Variable

• Starten von groovyConsole und Eingabe von

println „Hallo Welt“

mit anschliessendem STRG-R

Getting started

Thorsten Kamann ● thorsten.kamann@itemis.de 77

Getting started

Thorsten Kamann ● thorsten.kamann@itemis.de 88

Getting started: Embedding

Java-Anwendung

Bean-Scripting-Framework

(BSF)

Groovy-Shell

Groovy-Classloader

Groovy ScriptEngine

Groovy Script

ANTMaven

Thorsten Kamann ● thorsten.kamann@itemis.de 99

– Ist ein allgemeine Möglichkeit, jede beliebige Scriptsprache in Java-Anwendungen einzubinden

– Groovy bietet aber leichtgewichtigere und leistungsfähigere Möglichkeiten der Einbindung

Getting started: Embedding

Thorsten Kamann ● thorsten.kamann@itemis.de 1010

– Groovy-Shell bietet die Möglichkeit des Ein- und Auslesens von Variablen mittels des Binding-Objekts

Getting started: Embedding

Binding binding = new Binding();

binding.setVariable("foo", new Integer(2));

GroovyShell shell = new GroovyShell(binding);

Object value = shell.evaluate(

"println 'Hello World!'; x = 123; return foo * 10");

assert value == 20;

assert binding.getVariable("x„) == 123;

Thorsten Kamann ● thorsten.kamann@itemis.de 1111

– Lädt Groovy-Klassen dynamisch und ermöglicht den direkten Zugriff auf deren Methoden

Getting started: Embedding

ClassLoader parent = getClass().getClassLoader();

GroovyClassLoader loader = new

GroovyClassLoader(parent);

Class groovyClass = loader.parseClass(

new File("script.groovy"));

GroovyObject groovyObject =

(GroovyObject) groovyClass.newInstance();

Object[] args = {};

groovyObject.invokeMethod("run", args);

Thorsten Kamann ● thorsten.kamann@itemis.de 1212

– Lädt Groovy-Klassen dynamisch und ermöglicht den direkten Zugriff auf deren Methoden

Getting started: Embedding

GroovyClassLoader gcl = new GroovyClassLoader();

Class clazz = gcl.parseClass(

myStringwithGroovyClassSource,

"SomeName.groovy");

Object aScript = clazz.newInstance();

MyInterface myObject = (MyInterface) aScript;

myObject.interfaceMethod();

Thorsten Kamann ● thorsten.kamann@itemis.de 1313

– Dies ist die leistungsfähige Möglichkeit, um Groovy-Skripte auszuführen.

Getting started: Embedding

String[] roots = new String[]

{"/my/groovy/script/path"};

GroovyScriptEngine gse = new GroovyScriptEngine(roots);

Binding binding = new Binding();

binding.setVariable("input", "world");

gse.run("hello.groovy", binding);

System.out.println(binding.getVariable("output"));

Thorsten Kamann ● thorsten.kamann@itemis.de 1414

– ANT-Task, mit dem eine beliebige Anzahl von Groovy-Skripten ausgeführt werden kann

– GroovyC-Task, der Groovy-Skripte (Klassen) zu Java Bytecode kompiliert

– Erstellen von Ant-Tasks mit Groovy und dem Ant-Builder

– Erzeugen von Ant-Skripten

Getting started: Embedding

Thorsten Kamann ● thorsten.kamann@itemis.de 1515

– Unterstützung mittels des M2-Ant-Plugins

– Auf http://mojo.codehaus.org/ existieren bereits Maven-Tools für direkte Unterstützung von Groovy:

• Groovy-Compiler

• Groovy-Archetype

• Tools, um Maven-Plugins mit Groovy zu entwickeln

Getting started: Embedding

Thorsten Kamann ● thorsten.kamann@itemis.de 1616

– Groovy kann direkt von der Eingabeaufforderunggroovy script.groovy [arguments]

ausgeführt werden

– Alternativ kann über den Dialog Ordneroptionen-->Dateitypen die Extension *.groovy an groovy.bat gebunden werden.

Getting started: Embedding

Thorsten Kamann ● thorsten.kamann@itemis.de 1717

– Groovy kann direkt von der Konsole mittelsgroovy script.groovy [arguments]

ausgeführt werden

– Alternativ kann in die 1. Zeile eines Groovy-Skripts#!/usr/bin/env groovy

eingefügt werden.

– So kann mit chmod +x script.groovy

./script.groovy

das Skript ausgeführt werden

Getting started: Embedding

Thorsten Kamann ● thorsten.kamann@itemis.de 1818

Thorsten Kamann ● thorsten.kamann@itemis.de 1919

– Package-, Import-Mechanismus

– Class und Method Definition

– Kontrollstrukturen (ausser for(init;test,inc))

– Operatoren, Ausdrücke und Zuweisungen

– Exeption Handling

– Literale

– Instantiierung, Referenzen

Die Syntax: Groovy vs. Java

Thorsten Kamann ● thorsten.kamann@itemis.de 2020

– Vereinfachter Zugriff auf Java-Objekte mit neuen Ausdrücken und Operatoren

– Zusätzliche Möglichkeiten, um Objekte zu erstellen

– Neue Konstrollstrukturen

– Neue Datentypen

– Alles ist ein Objekt

Die Syntax: Groovy vs. Java

Thorsten Kamann ● thorsten.kamann@itemis.de 2121

– groovy.lang.*, groovy.util.*

– java.lang.*, java.util.*, java.net.*, java.io.*

– java.math.BigInteger, java.math.BigDecimal

Die Syntax: Groovy vs. Java

Thorsten Kamann ● thorsten.kamann@itemis.de 2222

Die Syntax

assert(true)

assert 1 == 1

def x = 1

assert x == 1

def y=1; assert y == 1

Thorsten Kamann ● thorsten.kamann@itemis.de 2323

– Alles ist ein Objekt

– Keine primitiven Datentypen

– Automatisches Wrapping (Boxing/Unboxing)

– Optionales Typing

– Statisches/Dynamisches Typing

Die Syntax: Datentypen

Thorsten Kamann ● thorsten.kamann@itemis.de 2424

Die Syntax: Datentypen

Typ Beispiel

java.lang.Integer 15, 0x1234ffff

java.lang.Long 100L, 100l

java.lang.Float 1.23F, 1.23f

java.lang.Double 1.23D, 1.23d

java.math.BigInteger 123g, 456G

java.math.BigDecimal 1.23, 4.56, 1.4E4, 2.8e4, 1.23g, 1.23G

Thorsten Kamann ● thorsten.kamann@itemis.de 2525

– Whole word Matcher

– Find Matcher

– Count

– Foreach

– Replace

– Split

Die Syntax: Datentypen

Thorsten Kamann ● thorsten.kamann@itemis.de 2626

Die Syntax: Datentypen

//Finder

assert „Hello Groovy!“ =~ /o.G/

//Matcher

assert „Hello Groovy!“ ==~ /Hello\sGroovy\\!/

//Replace

assert „Hello Groovy!“.replaceAll(/Hello/, „Hi“)

== „Hi Groovy!“

//Split

assert „Hello Groovy!“.split(/ /).size == 2

Thorsten Kamann ● thorsten.kamann@itemis.de 2727

– Basieren auf einfachen Strings

– Bieten allerdings eine erweiterte Funktionalität

– Sie müssen in doppelten Anführungszeichen definiert werden

– Unterstützen Platzhalter• ${expression}

• $expression

Die Syntax: Datentypen

Thorsten Kamann ● thorsten.kamann@itemis.de 2828

Die Syntax: Datentypen

me = „Thorsten“

age = 34

location = „Neuss“

line = „Ich heisse $name, bin $age und wohne in $location“

assert line == „Ich heisse Thorsten, bin 34 und wohne in

Neuss“

assert line instancof java.lang.String

Thorsten Kamann ● thorsten.kamann@itemis.de 2929

Die Syntax: Datentypen

Start/End Zeichen Beispiel GString? Backslash?

Einfache Anführungszeichen ‚Hallo Thorsten„

Doppelte Anführungszeichen „Hallo $name“

Dreifache Anführungszeichen „„„----------------Total: $0.02---------------„„„

Dreifache doppelte Anführungszeichen

“““---------------Line with text--------------“““

Forward Slash /x(\d*)y/

Thorsten Kamann ● thorsten.kamann@itemis.de 3030

Die Syntax: Datentypen

greeting = „Hello Groovy!“

assert greeting[0] == „H“

assert greeting [6..11] == „Groovy“

assert ‚Hi‘ + greeting – ‚Hello‘ == „Hi Groovy!“

assert greeting.count(„o“) = 3

assert „x“.padLeft(3) == „ x“

assert „x“.padRight(3) == „x „

assert „x“.center(3) == „ x „

assert „x“ * 3 == „xxx“

Thorsten Kamann ● thorsten.kamann@itemis.de 3131

Die Syntax: Datentypen (collective)

List list = []

assert list.size == 0

list = [‚a‘, ‚b‘, ‚c‘]

assert list.size == 3 && list[1] = ‚b‘

list << ‚d‘

assert list.size == 4

list += ‚e‘

assert list.size == 5

assert list – ‚d‘ == [‚a‘, ‚b‘, ‚c‘, ‚e‘]

Thorsten Kamann ● thorsten.kamann@itemis.de 3232

– Sind Listen mit einem definierten Anfangs- und Endwert

– Nahezu jedes Objekt kann in einer Range verwaltet werden

• Methoden next und previous müssen implementiert werden

• Das Interface java.lang.Comparable muss implementiert werden

Die Syntax: Datentypen (collective)

Thorsten Kamann ● thorsten.kamann@itemis.de 3333

Die Syntax: Datentypen (collective)

def range = 0..10

assert range.contains(0)

assert range.contains(10)

range = 0..<10

assert range.contains(0)

assert !range.contains(10)

Thorsten Kamann ● thorsten.kamann@itemis.de 3434

Die Syntax: Datentypen (collective)

Map map = [:]

assert map.size == 0

map = [a:1, b:2,c:3]

assert map.size = 3

assert map.get(„a“) == 1

assert map[‚b‘] == 2

assert map.c == 3

map.e = 4

assert map.e == 4

Thorsten Kamann ● thorsten.kamann@itemis.de 3535

– Expandos ermöglichen die Erzeugung von dynamischen Objekten

Die Syntax: Datentypen (collective)

def player = new Expando()

player.name = “Thorsten"

player.greeting = { "Hello, my name is $player.name" }

assert player.greeting() == "Hello, my name is Thorsten"

Thorsten Kamann ● thorsten.kamann@itemis.de 3636

– Codeblöcke

– Können einen Wert/Objekt zurückgeben

– Referenzieren und verwenden Variablen

– call()(implizit/explizit) führt die Closure aus

– Können an eine Variable gebunden werden

– Ähneln Java Inner Classes

Die Syntax: Closures

Thorsten Kamann ● thorsten.kamann@itemis.de 3737

Die Syntax: Closures

List list = [1, 2, 3]

list.each{ entry ->

println „entry $entry“

}

Ausgabe:

entry 1

entry 2

entry 3

Thorsten Kamann ● thorsten.kamann@itemis.de 3838

Die Syntax: Closures

public void each(Closure closure){

for (it: listItems){

closure(it).call();

}

}

Thorsten Kamann ● thorsten.kamann@itemis.de 3939

Die Syntax: Closures

Class MethodClosureSample(){

boolean validate(String value){

return StringUtils.isNotEmpty(value);

}

}

MethodClosureSample sample = new MethodeClosureSample()

List success = [„Hello“, „World“, „!“]

List fails = [„Hello“, „“, „World“, „!“]

assert success.each(sample.&validate)

assert !fails.each(sample.&validate)

Thorsten Kamann ● thorsten.kamann@itemis.de 4040

– Transformiert eine Closure mit vielen Parametern in eine Closure mit weniger Parametern

– Dabei werden Parameter mit Werten vorbelegt

Die Syntax: Closures

def adder = {x, y -> return x+y}

def addOne = adder.curry(1)

assert addOne(5) == 6

Thorsten Kamann ● thorsten.kamann@itemis.de 4141

Die Syntax: Closures

Closure Beschreibung

collect Sammelt Objekte und fügt sie in eine neue Liste ein

each Führt für jedes Element aus

find Findet ein Element

findAll Findet alle Elemente anhand von Kriterien

min(Comparator) Gibt den min. Wert aus der Collection zurück

max(Comparator) Gibt den max. Wert aus der Collection zurück

sort(Comparator) Sortiert die Collection (Comparator ist optional)

unique Entfernt doppelte Werte aus der Collection

Thorsten Kamann ● thorsten.kamann@itemis.de 4242

Die Syntax: Kontrollstrukturen

Runtime type Evaluation criterion required for truth

Boolean Booleanwert muss true sein

Matcher Der reguläre Ausdruck muss mindestens 1 Treffer haben

Collection Die Collection darf nicht leer sein

Map Die Map darf nicht leer sein

String Der String darf ebenfalls nicht leer sein

Number Muss ungleich 0 sein

Alles andere Die Objektreferenz muss ungleich null sein

Thorsten Kamann ● thorsten.kamann@itemis.de 4343

Die Syntax: If-Statement

If (true) assert true

Else assert false

If (1){ assert true

}else{ assert false

}

If (0) assert false

Else if (1) assert true

Else assert false

(1 > 0)? assert true: assert False

Thorsten Kamann ● thorsten.kamann@itemis.de 4444

– Kann mit jedem Datentyp verwendet werden

Die Syntax: Kontrollstrukturen

switch (10){

case 0 : assert false; break;

case 0..9 : assert false; break;

case [8,9,11] : assert false; break;

case Float : assert false; break;

case {it%3==0} : assert false; break;

case ~/../ : assert true; break;

default : assert false; break;

}

Thorsten Kamann ● thorsten.kamann@itemis.de 4545

Die Syntax: Looping

def list = [1, 2, 3, 4, 5]

while (list){

list.remove()

}

assert list == []

while (list.size() < 3){

list << list.size()+1

}

assert list == [1, 2, 3]

Thorsten Kamann ● thorsten.kamann@itemis.de 4646

Die Syntax: Looping

for (String i in ‘a‘..‘c‘) store += i

assert store == ‘abc‘

for (i in [1, 2, 3]){ store += i}

assert store == ‘123‘

def myString = ‘Hello Groovy!‘

for (i in 0..myString.size()){ store += myString[i]}

assert store == myString

Entspricht dem Java Equivalent:for (int i=0;i<upperBound;i++){}

Thorsten Kamann ● thorsten.kamann@itemis.de 4747

Die Syntax: Return/Break/Continue

Boolean someMethod(){

if (false){

return false

}

return true

}

Thorsten Kamann ● thorsten.kamann@itemis.de 4848

Die Syntax: Return/Break/Continue

while (true){

if (someCondition){

break

}

}

Thorsten Kamann ● thorsten.kamann@itemis.de 4949

Die Syntax: Return/Break/Continue

for(item in items){

if (someCondition){

continue

}

}

Thorsten Kamann ● thorsten.kamann@itemis.de 5050

– Ähnliche Unterstützung wie in Java

• try-catch-finally

• try-catch

• try-finally

– Checked-Exception werden als Runtime-Excpetion hochgereicht

Die Syntax: Exception

Thorsten Kamann ● thorsten.kamann@itemis.de 5151

– Identisch mit Klassen in Java

– Können Felder, Konstruktoren, Methoden enthalten

– Konstruktoren und Methoden können lokale Variablen verwenden

Die Syntax: OO und Groovy

Thorsten Kamann ● thorsten.kamann@itemis.de 5252

– Lokale Variablen und Felder müssen deklariert werden

– Java Modifiers werden verwendet:

• private, protected, public, final, static

• Bei fehlendem Modifier wird eine Property erzeugt

Die Syntax: OO und Groovy

Thorsten Kamann ● thorsten.kamann@itemis.de 5353

Die Syntax: OO und Groovy

def map = [a:[b:[c:1]]]

assert map.a.b.c == 1

try{

assert map a.x.c == null

}catch (NullPointerException npe){

}

assert map?.a.?x?.c == null

Fängt die NPE

Thorsten Kamann ● thorsten.kamann@itemis.de 5454

Thorsten Kamann ● thorsten.kamann@itemis.de 5555

– Sind wie JavaBeans

– Getter/Setter werden zur Laufzeit erzeugt

– Event-Support wird mit vereinfachten Methoden ermöglicht

Groovy Beans

Thorsten Kamann ● thorsten.kamann@itemis.de 5656

Groovy Beans

Customer.groovy:class Customer {

int idString name

}

Customer.java:public class Customer {private int id = 0;private String name;

public int getId(){return id;

} public void setId(int id){

this.id = id;}...

}

Thorsten Kamann ● thorsten.kamann@itemis.de 5757

– Wenn eine Property als private gekennzeichnet

ist, wird ein Java Field benutzt, um diese Property zu repräsentieren

Groovy Beans

Thorsten Kamann ● thorsten.kamann@itemis.de 5858

– Wenn eine Property als public oder protected

gekennzeichnet wird, werden Getter- und Setter-Methoden mit der gleichen Sichtbarkeit und ein Feld mit der Sichtbarkeit private auf Bytecode-

Ebene erzeugt

Groovy Beans

Thorsten Kamann ● thorsten.kamann@itemis.de 5959

– Wenn keine Getter- oder Setter-Methoden für Properties mit der Sichtbarkeit public oder protected deklariert wurden, werden fehlende

Getter- und Setter-Methoden mit der gleichen Sichtbarkeit automatisch auf Bytecode-Ebene erzeugt

Groovy Beans

Thorsten Kamann ● thorsten.kamann@itemis.de 6060

– Mit selbst deklarierten Getter- und Setter-Methoden können die von der Groovy-Runtimegenerierten Methoden überschrieben werden

Groovy Beans

Thorsten Kamann ● thorsten.kamann@itemis.de 6161

Groovy Beans

Groovy:def button = new JButton(Push me!”)

button.actionPerformed = {event ->println button.text

}

Java:final JButton button =

new Jbutton(„Push me!“);button.addEventListener(

new IActionListener(){public void actionPerformed(

ActionEvent event){System.out.println(button.getText());

}});

Thorsten Kamann ● thorsten.kamann@itemis.de 6262

Thorsten Kamann ● thorsten.kamann@itemis.de 6363

XML-Processing

XML-Support

Edit

XML-Parser

XMLSlurper

DOMCategroy

Create

MarkupBuilder

NodeBuilder

DOM StAX DOM4J JAXEN

SAX XOM JDOM XPATH

DOM4JDOM

XOM JDOM

Thorsten Kamann ● thorsten.kamann@itemis.de 6464

– Groovy bietet reichhaltige Unterstützung für das XML-Processing

– GPath (Xpath) Ausdrücke erlauben schnelle Navigation im XML-Dokument

– DOMCategory stellt mächtige Navigationselemente zur Verfügung

XML-Processing

Thorsten Kamann ● thorsten.kamann@itemis.de 6565

XML-Processing

DOM Element Expression Beschreibung

Element .elementName.„elementName„

Alle Kindelemente mit dem angegebenen Namen

Element [index] Kindelement mit dem [index]

Element .@attrName.„@attrName„.[„@attrName„]

Attribut mit den angebenen Namen

Element .name() Name des aktuellen Elements

Element .parent() Das Elternelement

Element .text() Der Textinhalt des Elements

Thorsten Kamann ● thorsten.kamann@itemis.de 6666

XML-Processing

//XML-Parser

def xml = new XmlParser().parseText(SOME_XML_TEXT)

//XML-Slurper

def xml = new XmlSlurper().parseText(SOME_XML_TEXT)

//DOMCategory

def reader = new StringReader(SOME_XML_TEXT)

def doc = DOMBuilder.parse(reader)

def records = doc.documentElement

use (DOMCategory) {

//do something

}

Thorsten Kamann ● thorsten.kamann@itemis.de 6767

Thorsten Kamann ● thorsten.kamann@itemis.de 6868

– Groovy bietet Unterstützung für die Arbeit mit Baumartige Strukturen:

• XML, HTML, Ant Tasks, Swing UI's, SWT UI„s

Groovy Builder

XML HTML ANT Swing SWTYour

Builder

GroovyObjectSupport

BuilderSupport

Thorsten Kamann ● thorsten.kamann@itemis.de 6969

– eine einheitliche Schnittstelle

• Elemente sind Closures

• Attribute sind Maps

– Vollständige Integration anderer Groovy-Features

• Collections

• Arrays

• Conditions

• ...

Groovy Builder

Thorsten Kamann ● thorsten.kamann@itemis.de 7070

Groovy Builder

builder = new

MarkupBuilder(writer)

builder.person() {

name(first:“Thorsten",

last:“Kamann") {

age("34")

}

}

<person>

<name first=“Thorsten“

last=“Kamann“>

<age>34</age>

</name>

</person>

Thorsten Kamann ● thorsten.kamann@itemis.de 7171

Groovy Builder

def writer = new FileWriter(“markup.html“)

def html = new groovy.xml.MarkupBuilder(writer)

html.html{

head{

title ‘Hello Groovy!‘

}

body{

h1 ‘Hello Groovy‘

p(style:‘font-weight: bold;‘,

‘This is built by Groovy.‘)

}

}

Thorsten Kamann ● thorsten.kamann@itemis.de 7272

Groovy Builder

Thorsten Kamann ● thorsten.kamann@itemis.de 7373

Groovy Builder

def ant = new groovy.util.AntBuilder()

ant.mkdir(dir:myDir)

ant.copy(todir:myDir) {

fileset(dir:"src/test") {

include(name:"**/*.groovy")

}

}

Thorsten Kamann ● thorsten.kamann@itemis.de 7474

Groovy Builder

def swing = new groovy.swing.SwingBuilder()

def frame = swing.frame(title:'Password'){

passwordField(columns:30, actionPerformed: {event ->

println event.source.text

System.exit(0)

})

}

frame.pack()

frame.show()

Thorsten Kamann ● thorsten.kamann@itemis.de 7575

Groovy Builder

Thorsten Kamann ● thorsten.kamann@itemis.de 7676

Groovy Builder

bb = new grails.spring.BeanBuilder()

bb.beans{

CustomerService(org.x.y.z.CustomerServiceImpl){

customerDao = CustomerDao

}

CustomerDao(org.x.y.z.CustomerDaoImpl){

sessionFactory = MySessionFactory

}

ApplicationContext context =

bb.createApplicationContext()

}

Thorsten Kamann ● thorsten.kamann@itemis.de 7777

Thorsten Kamann ● thorsten.kamann@itemis.de 7878

Testing

Groovy Testing

Unit

TPTP

Mocks

Stubs

UI-Test Webservice-TestCoverage

jUnit Corbertura

Canoo WebtestHTML Unit

SoapUI

Thorsten Kamann ● thorsten.kamann@itemis.de 7979

– jUnit ist in der Groovy-Runtime verankert

– Zusätzliche Assert-Statements

– Leicht integrierbar mit Ant und Maven

– Groovy liefert auch Groovy Mocks

Testing

Thorsten Kamann ● thorsten.kamann@itemis.de 8080

Testing

assertArrayEquals(Object[] expected, Object[] value)

assertLength(int length, char[] array)

assertLength(int length, int[] array)

assertLength(int length, Object[] array)

assertContains(char expected, char[] array)

assertContains(int expected, int[] array)

assertToString(Object value, String expected)

assertInspect(Object value, String expected)

assertScript(final String script)

shouldFail(Closure code)

shouldFail(Class clazz, Closure code)

Thorsten Kamann ● thorsten.kamann@itemis.de 8181

Testing

import groovy.mock.interceptor.MockFor

def mocker = new MockFor(Collaborator.class)

mocker.demand.one(1..2) { 1 }

mocker.demand.two() { 2 }

mocker.use {

def caller = new Caller()

assertEquals 1, caller.collaborateOne()

assertEquals 1, caller.collaborateOne()

assertEquals 2, caller.collaborateTwo()

}

Thorsten Kamann ● thorsten.kamann@itemis.de 8282

– Resourcen (*.xml, Spring) können zur Laufzeit erzeugt werden

– Zugriffe auf private Java-Ressourcen sind einfacher (kein Reflection)

– Stubs und Mocks sind einfacher

– 100%ige Integration in den Buildprozess (Ant, Maven)

Testing

Thorsten Kamann ● thorsten.kamann@itemis.de 8383

Thorsten Kamann ● thorsten.kamann@itemis.de 8484

– MVC-Framework

• Basierend auf Spring-MVC und Hibernate

– JSP oder GSP

– Einfache AJAX-Integration

– Sehr performant

– Integrierter Job-Scheduler

Grails

Thorsten Kamann ● thorsten.kamann@itemis.de 8585

– Domänenklassen (mit GORM)

– Controller

– Services

– Jobs

– CRUD-Anwendung in No-Time

– AJAX (Dojo, Yahoo, Scriptacolous, Prototype)

– Vollständig integriert

Grails

Thorsten Kamann ● thorsten.kamann@itemis.de 8686

Thorsten Kamann ● thorsten.kamann@itemis.de 8787

Groovy Module

class Client{

String name

String email

Address address

static hasMany = [orders: Order]

static constraints = {

name(blank:false,size:5..20)

email(email:true)

}

}

Einfache Properties

1:* Beziehungstatic belongsTo=Client

Constraints

1:1 Beziehung

Thorsten Kamann ● thorsten.kamann@itemis.de 8888

Groovy Module

Thorsten Kamann ● thorsten.kamann@itemis.de 8989

Thorsten Kamann ● thorsten.kamann@itemis.de 9090

– Assistenten für Groovy-Klassen und –Unittests

– Komplette Integration in Eclipse

– Syntax-Coloring

– Syntax-Checking

– Word-Completion

– Duck-Typing

IDE-Support

Thorsten Kamann ● thorsten.kamann@itemis.de 9191

IDE-Support

Instance variable completion

Method completion asGroovy Properties

Complexcompletion

Thorsten Kamann ● thorsten.kamann@itemis.de 9292

IDE-Support

Typed local variable Duck-Typing

Thorsten Kamann ● thorsten.kamann@itemis.de 9393

Thorsten Kamann ● thorsten.kamann@itemis.de 9494

Links und Ressourcen

Groovy in Actionvon Dierk Koenig, Andrew Glover, Paul King, Guillaume Laforge

- Taschenbuch: 696 Seiten- Verlag: Manning (Januar 2007)- Sprache: Englisch- ISBN-10: 1932394842- ISBN-13: 978-1932394849

Thorsten Kamann ● thorsten.kamann@itemis.de 9595

• Groovy Webseitehttp://groovy.codehaus.org/

• Groovy Series Podcasthttp://groovy.codehaus.org/Groovy+Series

• Groovy Blogshttp://www.groovyblogs.org/

• Webseite des Referenten (Blog, Wiki)http://www.thorsten-kamann.de

Links und Ressourcen

Thorsten Kamann ● thorsten.kamann@itemis.de 9696

top related