diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml
index 2a058e5358..d6097af208 100644
--- a/testing-modules/groovy-spock/pom.xml
+++ b/testing-modules/groovy-spock/pom.xml
@@ -48,9 +48,9 @@
- 1.0-groovy-2.4
+ 1.3-RC1-groovy-2.4
2.4.7
1.5
-
\ No newline at end of file
+
diff --git a/testing-modules/groovy-spock/src/main/java/mocks/EventPublisher.java b/testing-modules/groovy-spock/src/main/java/mocks/EventPublisher.java
new file mode 100644
index 0000000000..290966db9f
--- /dev/null
+++ b/testing-modules/groovy-spock/src/main/java/mocks/EventPublisher.java
@@ -0,0 +1,7 @@
+package mocks;
+
+public interface EventPublisher {
+
+ void publish(String addedOfferId);
+
+}
diff --git a/testing-modules/groovy-spock/src/main/java/mocks/ExternalItemProviderException.java b/testing-modules/groovy-spock/src/main/java/mocks/ExternalItemProviderException.java
new file mode 100644
index 0000000000..e2ac43b7f4
--- /dev/null
+++ b/testing-modules/groovy-spock/src/main/java/mocks/ExternalItemProviderException.java
@@ -0,0 +1,5 @@
+package mocks;
+
+public class ExternalItemProviderException extends RuntimeException {
+
+}
diff --git a/testing-modules/groovy-spock/src/main/java/mocks/Item.java b/testing-modules/groovy-spock/src/main/java/mocks/Item.java
new file mode 100644
index 0000000000..e1608cfd23
--- /dev/null
+++ b/testing-modules/groovy-spock/src/main/java/mocks/Item.java
@@ -0,0 +1,36 @@
+package mocks;
+
+import java.util.Objects;
+
+public class Item {
+ private final String id;
+ private final String name;
+
+ public Item(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Item item = (Item) o;
+ return Objects.equals(id, item.id) &&
+ Objects.equals(name, item.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name);
+ }
+
+}
diff --git a/testing-modules/groovy-spock/src/main/java/mocks/ItemProvider.java b/testing-modules/groovy-spock/src/main/java/mocks/ItemProvider.java
new file mode 100644
index 0000000000..a794c51f49
--- /dev/null
+++ b/testing-modules/groovy-spock/src/main/java/mocks/ItemProvider.java
@@ -0,0 +1,9 @@
+package mocks;
+
+import java.util.List;
+
+public interface ItemProvider {
+
+ List- getItems(List itemIds);
+
+}
diff --git a/testing-modules/groovy-spock/src/main/java/mocks/ItemService.java b/testing-modules/groovy-spock/src/main/java/mocks/ItemService.java
new file mode 100644
index 0000000000..3327a8b27c
--- /dev/null
+++ b/testing-modules/groovy-spock/src/main/java/mocks/ItemService.java
@@ -0,0 +1,37 @@
+package mocks;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ItemService {
+ private final ItemProvider itemProvider;
+ private final EventPublisher eventPublisher;
+
+
+ public ItemService(ItemProvider itemProvider, EventPublisher eventPublisher) {
+ this.itemProvider = itemProvider;
+ this.eventPublisher = eventPublisher;
+ }
+
+ List
- getAllItemsSortedByName(List itemIds) {
+ List
- items;
+ try{
+ items = itemProvider.getItems(itemIds);
+ } catch (RuntimeException ex) {
+ throw new ExternalItemProviderException();
+ }
+ return items.stream()
+ .sorted(Comparator.comparing(Item::getName))
+ .collect(Collectors.toList());
+ }
+
+ void saveItems(List itemIds) {
+ List notEmptyOfferIds = itemIds.stream()
+ .filter(itemId -> !itemId.isEmpty())
+ .collect(Collectors.toList());
+ // save in database
+ notEmptyOfferIds.forEach(eventPublisher::publish);
+ }
+
+}
diff --git a/testing-modules/groovy-spock/src/main/java/mocks/LoggingEventPublisher.java b/testing-modules/groovy-spock/src/main/java/mocks/LoggingEventPublisher.java
new file mode 100644
index 0000000000..c51fe1ff77
--- /dev/null
+++ b/testing-modules/groovy-spock/src/main/java/mocks/LoggingEventPublisher.java
@@ -0,0 +1,10 @@
+package mocks;
+
+public class LoggingEventPublisher implements EventPublisher {
+
+ @Override
+ public void publish(String addedOfferId) {
+ System.out.println("I've published: " + addedOfferId);
+ }
+
+}
diff --git a/testing-modules/groovy-spock/src/test/groovy/mocks/ItemServiceUnitTest.groovy b/testing-modules/groovy-spock/src/test/groovy/mocks/ItemServiceUnitTest.groovy
new file mode 100644
index 0000000000..2ccb72f726
--- /dev/null
+++ b/testing-modules/groovy-spock/src/test/groovy/mocks/ItemServiceUnitTest.groovy
@@ -0,0 +1,131 @@
+package mocks
+
+import spock.lang.Specification
+
+class ItemServiceUnitTest extends Specification {
+
+ ItemProvider itemProvider
+ ItemService itemService
+ EventPublisher eventPublisher
+
+ def setup() {
+ itemProvider = Stub(ItemProvider)
+ eventPublisher = Mock(EventPublisher)
+ itemService = new ItemService(itemProvider, eventPublisher)
+ }
+
+ def 'should return items sorted by name'() {
+ given:
+ def ids = ['offer-id', 'offer-id-2']
+ itemProvider.getItems(ids) >> [new Item('offer-id-2', 'Zname'), new Item('offer-id', 'Aname')]
+
+ when:
+ List
- items = itemService.getAllItemsSortedByName(ids)
+
+ then:
+ items.collect { it.name } == ['Aname', 'Zname']
+ }
+
+ def 'arguments constraints'() {
+ itemProvider.getItems(['offer-id'])
+ itemProvider.getItems(_) >> []
+ itemProvider.getItems(*_) >> []
+ itemProvider.getItems(!null) >> []
+ itemProvider.getItems({ it.size > 0 }) >> []
+ }
+
+ def 'should return different items on subsequent call'() {
+ given:
+ itemProvider.getItems(_) >>> [
+ [],
+ [new Item('1', 'name')],
+ [new Item('2', 'name')]
+ ]
+
+ when: 'method is called for the first time'
+ List
- items = itemService.getAllItemsSortedByName(['not-important'])
+
+ then: 'empty list is returned'
+ items == []
+
+ when: 'method is called for the second time'
+ items = itemService.getAllItemsSortedByName(['not-important'])
+
+ then: 'item with id=1 is returned'
+ items == [new Item('1', 'name')]
+
+ when: 'method is called for the thirdtime'
+ items = itemService.getAllItemsSortedByName(['not-important'])
+
+ then: 'item with id=2 is returned'
+ items == [new Item('2', 'name')]
+ }
+
+ def 'should throw ExternalItemProviderException when ItemProvider fails'() {
+ given:
+ itemProvider.getItems(_) >> { new RuntimeException()}
+
+ when:
+ itemService.getAllItemsSortedByName([])
+
+ then:
+ thrown(ExternalItemProviderException)
+ }
+
+ def 'chaining response'() {
+ itemProvider.getItems(_) >>> { new RuntimeException() } >> new SocketTimeoutException() >> [new Item('id', 'name')]
+ }
+
+ def 'should return different items for different ids lists'() {
+ given:
+ def firstIds = ['first']
+ def secondIds = ['second']
+ itemProvider.getItems(firstIds) >> [new Item('first', 'Zname')]
+ itemProvider.getItems(secondIds) >> [new Item('second', 'Aname')]
+
+ when:
+ def firstItems = itemService.getAllItemsSortedByName(firstIds)
+ def secondItems = itemService.getAllItemsSortedByName(secondIds)
+
+ then:
+ firstItems.first().name == 'Zname'
+ secondItems.first().name == 'Aname'
+ }
+
+ def 'should publish events about new non-empty saved offers'() {
+ given:
+ def offerIds = ['', 'a', 'b']
+
+ when:
+ itemService.saveItems(offerIds)
+
+ then:
+ 2 * eventPublisher.publish({ it != null && !it.isEmpty()})
+ }
+
+ def 'should return items'() {
+ given:
+ itemProvider = Mock(ItemProvider)
+ itemProvider.getItems(['item-id']) >> [new Item('item-id', 'name')]
+ itemService = new ItemService(itemProvider, eventPublisher)
+
+ when:
+ def items = itemService.getAllItemsSortedByName(['item-id'])
+
+ then:
+ items == [new Item('item-id', 'name')]
+ }
+
+ def 'should spy on EventPublisher method call'() {
+ given:
+ LoggingEventPublisher eventPublisher = Spy(LoggingEventPublisher)
+ itemService = new ItemService(itemProvider, eventPublisher)
+
+ when:
+ itemService.saveItems(['item-id'])
+
+ then:
+ 1 * eventPublisher.publish('item-id')
+ }
+
+}