1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 
6 package org.mockitousage.basicapi;
7 
8 import org.junit.Test;
9 import org.mockito.exceptions.base.MockitoException;
10 import org.mockitousage.IMethods;
11 
12 import static org.assertj.core.api.Assertions.assertThat;
13 import static org.junit.Assert.fail;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.withSettings;
16 import static org.mockitoutil.ClassLoaders.inMemoryClassLoader;
17 import static org.mockitoutil.SimpleClassGenerator.makeMarkerInterface;
18 
19 // See issue 453
20 public class MockingMultipleInterfacesTest {
21 
22     class Foo {}
23     interface IFoo {}
24     interface IBar {}
25 
26     @Test
should_allow_multiple_interfaces()27     public void should_allow_multiple_interfaces() {
28         //when
29         Foo mock = mock(Foo.class, withSettings().extraInterfaces(IFoo.class, IBar.class));
30 
31         //then
32         assertThat(mock).isInstanceOf(IFoo.class);
33         assertThat(mock).isInstanceOf(IBar.class);
34     }
35 
36     @Test
should_scream_when_null_passed_instead_of_an_interface()37     public void should_scream_when_null_passed_instead_of_an_interface() {
38         try {
39             //when
40             mock(Foo.class, withSettings().extraInterfaces(IFoo.class, null));
41             fail();
42         } catch (MockitoException e) {
43             //then
44             assertThat(e.getMessage()).contains("extraInterfaces() does not accept null parameters");
45         }
46     }
47 
48     @Test
should_scream_when_no_args_passed()49     public void should_scream_when_no_args_passed() {
50         try {
51             //when
52             mock(Foo.class, withSettings().extraInterfaces());
53             fail();
54         } catch (MockitoException e) {
55             //then
56             assertThat(e.getMessage()).contains("extraInterfaces() requires at least one interface");
57         }
58     }
59 
60     @Test
should_scream_when_null_passed_instead_of_an_array()61     public void should_scream_when_null_passed_instead_of_an_array() {
62         try {
63             //when
64             mock(Foo.class, withSettings().extraInterfaces((Class[]) null));
65             fail();
66         } catch (MockitoException e) {
67             //then
68             assertThat(e.getMessage()).contains("extraInterfaces() requires at least one interface");
69         }
70     }
71 
72     @Test
should_scream_when_non_interface_passed()73     public void should_scream_when_non_interface_passed() {
74         try {
75             //when
76             mock(Foo.class, withSettings().extraInterfaces(Foo.class));
77             fail();
78         } catch (MockitoException e) {
79             //then
80             assertThat(e.getMessage()).contains("Foo which is not an interface");
81         }
82     }
83 
84     @Test
should_scream_when_the_same_interfaces_passed()85     public void should_scream_when_the_same_interfaces_passed() {
86         try {
87             //when
88             mock(IMethods.class, withSettings().extraInterfaces(IMethods.class));
89             fail();
90         } catch (MockitoException e) {
91             //then
92             assertThat(e.getMessage()).contains("You mocked following type: IMethods");
93         }
94     }
95 
96 
97     @Test
should_mock_class_with_interfaces_of_different_class_loader_AND_different_classpaths()98     public void should_mock_class_with_interfaces_of_different_class_loader_AND_different_classpaths() throws ClassNotFoundException {
99         // Note : if classes are in the same classpath, SearchingClassLoader can find the class/classes and load them in the first matching classloader
100         Class<?> interface1 = inMemoryClassLoader()
101                 .withClassDefinition("test.Interface1", makeMarkerInterface("test.Interface1"))
102                 .build()
103                 .loadClass("test.Interface1");
104         Class<?> interface2 = inMemoryClassLoader()
105                 .withClassDefinition("test.Interface2", makeMarkerInterface("test.Interface2"))
106                 .build()
107                 .loadClass("test.Interface2");
108 
109         Object mocked = mock(interface1, withSettings().extraInterfaces(interface2));
110         assertThat(interface2.isInstance(mocked)).describedAs("mock should be assignable from interface2 type").isTrue();
111     }
112 }
113