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.Before; 8 import org.junit.Ignore; 9 import org.junit.Test; 10 11 import java.util.LinkedList; 12 import java.util.List; 13 import java.util.concurrent.Executor; 14 import java.util.concurrent.Executors; 15 import java.util.concurrent.RejectedExecutionException; 16 17 import static java.util.Collections.synchronizedList; 18 import static org.junit.Assert.fail; 19 import static org.mockito.Mockito.mock; 20 import static org.mockito.Mockito.when; 21 22 @Ignore 23 public class MultithreadedStubbingHalfManualTest { 24 25 /** 26 * Class with two methods, one of them is repeatedly mocked while another is repeatedly called. 27 */ 28 public interface ToMock { getValue(Integer param)29 Integer getValue(Integer param); 30 getValues(Integer param)31 List<Integer> getValues(Integer param); 32 } 33 34 /** 35 * Thread pool for concurrent invocations. 36 */ 37 private Executor executor; 38 39 private List<Exception> exceptions = synchronizedList(new LinkedList<Exception>()); 40 41 @Before setUp()42 public void setUp() { 43 this.executor = Executors.newSingleThreadExecutor(); 44 } 45 46 /** 47 * The returned runnable simply calls ToMock.getValues(int). 48 * 49 * @param toMock The mocked object 50 * @return The runnable. 51 */ getConflictingRunnable(final ToMock toMock)52 private Runnable getConflictingRunnable(final ToMock toMock) { 53 return new Runnable() { 54 public void run() { 55 while (true) { 56 try { 57 Thread.sleep((long) (Math.random() * 10)); 58 } catch (InterruptedException e) { 59 } 60 if (!toMock.getValues(0).isEmpty()) { 61 fail("Shouldn't happen, were just making sure it wasn't optimized away..."); 62 } 63 } 64 } 65 }; 66 } 67 68 @Test 69 //this problem shows at 4 out of 5 executions 70 //it is not strictly a bug because Mockito does not support simultanous stubbing (see FAQ) 71 //however I decided to synchronize some calls in order to make the exceptions nicer 72 public void tryToRevealTheProblem() { 73 ToMock toMock = mock(ToMock.class); 74 for (int i = 0; i < 100; i++) { 75 int j = i % 11; 76 77 // Repeated mocking 78 when(toMock.getValue(i)).thenReturn(j); 79 //TODO make it also showing errors for doReturn() 80 // doReturn(j).when(toMock).getValue(i); 81 82 while (true) { 83 try { 84 // Scheduling invocation 85 this.executor.execute(getConflictingRunnable(toMock)); 86 break; 87 } catch (RejectedExecutionException ex) { 88 fail(); 89 } 90 } 91 92 try { 93 Thread.sleep(10 / ((i % 10) + 1)); //NOPMD 94 } catch (InterruptedException e) { 95 } 96 } 97 } 98 } 99