1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockitousage.bugs; 6 7 import org.junit.Assert; 8 import org.junit.Test; 9 import org.mockito.Mockito; 10 import org.mockito.invocation.InvocationOnMock; 11 import org.mockito.stubbing.Answer; 12 13 import java.util.concurrent.ExecutorService; 14 import java.util.concurrent.Executors; 15 import java.util.concurrent.TimeUnit; 16 import java.util.concurrent.atomic.AtomicInteger; 17 18 //see bug 190 19 public class ShouldNotDeadlockAnswerExecutionTest { 20 21 @Test failIfMockIsSharedBetweenThreads()22 public void failIfMockIsSharedBetweenThreads() throws Exception { 23 Service service = Mockito.mock(Service.class); 24 ExecutorService threads = Executors.newCachedThreadPool(); 25 AtomicInteger counter = new AtomicInteger(2); 26 27 // registed answer on verySlowMethod 28 29 Mockito.when(service.verySlowMethod()).thenAnswer(new LockingAnswer(counter)); 30 31 // execute verySlowMethod twice in separate threads 32 33 threads.execute(new ServiceRunner(service)); 34 threads.execute(new ServiceRunner(service)); 35 36 // waiting for threads to finish 37 38 threads.shutdown(); 39 40 if (!threads.awaitTermination(1000, TimeUnit.MILLISECONDS)) { 41 // threads were timed-out 42 Assert.fail(); 43 } 44 } 45 46 @Test successIfEveryThreadHasItsOwnMock()47 public void successIfEveryThreadHasItsOwnMock() throws Exception { 48 Service service1 = Mockito.mock(Service.class); 49 Service service2 = Mockito.mock(Service.class); 50 ExecutorService threads = Executors.newCachedThreadPool(); 51 AtomicInteger counter = new AtomicInteger(2); 52 53 // registed answer on verySlowMethod 54 55 Mockito.when(service1.verySlowMethod()).thenAnswer(new LockingAnswer(counter)); 56 Mockito.when(service2.verySlowMethod()).thenAnswer(new LockingAnswer(counter)); 57 58 // execute verySlowMethod twice in separate threads 59 60 threads.execute(new ServiceRunner(service1)); 61 threads.execute(new ServiceRunner(service2)); 62 63 // waiting for threads to finish 64 65 threads.shutdown(); 66 67 if (!threads.awaitTermination(500, TimeUnit.MILLISECONDS)) { 68 // threads were timed-out 69 Assert.fail(); 70 } 71 } 72 73 static class LockingAnswer implements Answer<String> { 74 75 private AtomicInteger counter; 76 LockingAnswer(AtomicInteger counter)77 public LockingAnswer(AtomicInteger counter) { 78 this.counter = counter; 79 } 80 81 /** 82 * Decrement counter and wait until counter has value 0 83 */ answer(InvocationOnMock invocation)84 public String answer(InvocationOnMock invocation) throws Throwable { 85 counter.decrementAndGet(); 86 87 while (counter.get() != 0) { 88 Thread.sleep(10); 89 } 90 91 return null; 92 } 93 94 } 95 96 static class ServiceRunner implements Runnable { 97 98 private Service service; 99 ServiceRunner(Service service)100 public ServiceRunner(Service service) { 101 this.service = service; 102 } 103 run()104 public void run() { 105 service.verySlowMethod(); 106 } 107 108 } 109 110 interface Service { 111 verySlowMethod()112 String verySlowMethod(); 113 114 } 115 116 } 117 118