Spy, mock, stub in Spock Framework
This commit is contained in:
parent
46bad01ab9
commit
01ab66f84f
|
@ -48,9 +48,9 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<spock-core.version>1.0-groovy-2.4</spock-core.version>
|
||||
<spock-core.version>1.3-RC1-groovy-2.4</spock-core.version>
|
||||
<groovy-all.version>2.4.7</groovy-all.version>
|
||||
<gmavenplus-plugin.version>1.5</gmavenplus-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package mocks;
|
||||
|
||||
public class CharacterCalculator {
|
||||
|
||||
public int countCharacterInString(String value, char characterToCount) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
if (value.charAt(i) == characterToCount) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package mocks;
|
||||
|
||||
public interface EventPublisher {
|
||||
|
||||
void publish(String addedOfferId);
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package mocks;
|
||||
|
||||
public class ExternalItemProviderException extends RuntimeException {
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package mocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ItemProvider {
|
||||
|
||||
List<Item> getItems(List<String> itemIds);
|
||||
|
||||
}
|
|
@ -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<Item> getAllItemsSortedByName(List<String> itemIds) {
|
||||
List<Item> 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<String> itemIds) {
|
||||
List<String> notEmptyOfferIds = itemIds.stream()
|
||||
.filter(itemId -> !itemId.isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
// save in database
|
||||
notEmptyOfferIds.forEach(eventPublisher::publish);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package mocks;
|
||||
|
||||
public class LoggingEventPublisher implements EventPublisher {
|
||||
|
||||
@Override
|
||||
public void publish(String addedOfferId) {
|
||||
System.out.println("I've published: " + addedOfferId);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package mocks
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class ExampleSpockTest extends Specification {
|
||||
|
||||
CharacterCalculator characterCalculator
|
||||
|
||||
def setup() {
|
||||
characterCalculator = new CharacterCalculator()
|
||||
}
|
||||
|
||||
def 'should calculate character occurrences in given string'() {
|
||||
given:
|
||||
char characterToCount = 'o'
|
||||
String value = 'Hello world!'
|
||||
|
||||
when:
|
||||
int result = characterCalculator.countCharacterInString(value, characterToCount)
|
||||
|
||||
then:
|
||||
result == 2
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package mocks
|
||||
|
||||
import spock.lang.Specification
|
||||
|
||||
class ItemServiceTest 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<Item> 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<Item> 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')
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue