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 { | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										36
									
								
								testing-modules/groovy-spock/src/main/java/mocks/Item.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								testing-modules/groovy-spock/src/main/java/mocks/Item.java
									
									
									
									
									
										Normal file
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user