Skip to content

Commit dd85ff6

Browse files
Przemysław WojnowskiRobWin
authored andcommitted
Return DecoratedCall from clone() to preserve its contract. (ReactiveX#363)
DecoratedCall should return an object of the same type (DecoratedCall) to not break clone() contract on which other objects may relay on. X.clone() cannot return Y, should return X.
1 parent 55a73c8 commit dd85ff6

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

resilience4j-retrofit/src/main/java/io/github/resilience4j/retrofit/internal/DecoratedCall.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public boolean isCanceled() {
6666

6767
@Override
6868
public Call<T> clone() {
69-
return call.clone();
69+
return new DecoratedCall<>(call.clone());
7070
}
7171

7272
@Override

resilience4j-retrofit/src/test/java/io/github/resilience4j/retrofit/internal/DecoratedCallTest.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88

99
import java.io.IOException;
1010

11+
import static org.assertj.core.api.Assertions.assertThat;
1112
import static org.mockito.ArgumentMatchers.any;
1213
import static org.mockito.Mockito.mock;
1314

1415
@RunWith(JUnit4.class)
1516
public class DecoratedCallTest {
1617

18+
private final Call<String> call = mock(StringCall.class);
19+
private final Call<String> decorated = new DecoratedCall<>(call);
20+
1721
@Test
1822
public void passThroughCallsToDecoratedObject() throws IOException {
19-
final Call<String> call = mock(StringCall.class);
20-
final Call<String> decorated = new DecoratedCall<>(call);
21-
2223
decorated.cancel();
2324
Mockito.verify(call).cancel();
2425

@@ -41,6 +42,23 @@ public void passThroughCallsToDecoratedObject() throws IOException {
4142
Mockito.verify(call).execute();
4243
}
4344

45+
@Test
46+
public void cloneShouldReturnDecoratedCall() {
47+
Call<String> clonedTarget = mock(StringCall.class);
48+
Mockito.when(call.clone()).thenReturn(clonedTarget);
49+
50+
Call<String> clonedDecorator = decorated.clone();
51+
Mockito.verify(call).clone();
52+
assertThat(clonedDecorator).isInstanceOf(DecoratedCall.class);
53+
54+
decorated.request();
55+
Mockito.verify(call).request();
56+
Mockito.verifyNoMoreInteractions(call);
57+
58+
clonedDecorator.request();
59+
Mockito.verify(clonedTarget).request();
60+
}
61+
4462
private interface StringCall extends Call<String> {
4563
}
4664
}

0 commit comments

Comments
 (0)