android单元测试(4)Mockito与接⼝、抽象类、静态⽅法、
kotlin、模板
1.官⽅⽂档
2.模拟接⼝、抽象类、内部抽象类
2.1 模拟接⼝
1interface Interface1              {          fun say() = "said" }
2interface Interface2 : Interface1 { override fun say() = "said" }
3
4 @RunWith(AndroidJUnit4::class)
5class interface_test(){
6    @Test @SmallTest //测试 interface
7    fun test_mock_interface(){
8// mock creation
9        val mock = k(Interface1::class.java)
10// when
11        Mockito.`when`(mock.say()).thenReturn("mock said")
12// then
13        assertTrue(mock.say() == "mock said")
14
15// spy
16        val spy = spy(Interface1::class.java)
17        Mockito.`when`(spy.say()).thenReturn("spy said")
18        assertTrue(spy.say() == "spy said")
19    }
20 }
2.2 模拟抽象类
使⽤mock()并指定setting可以⽣成任意抽象类的模拟对象
使⽤spy()⽆法对构造有参数的抽象类⽣成模拟对象。
1abstract class Abstract1                    { fun say() = "said" }
2abstract class Abstract2(var name: String)  { fun say() = "said" }
3
4 @RunWith(AndroidJUnit4::class)
5class Abstract_test(){
6
7    @Test @SmallTest //测试⽆构造参数的 abstract 类
8    fun test_mock_abstract(){
9// mock creation
10        val mock = k(Abstract1::class.java)
11// when
12        Mockito.`when`(mock.say()).thenReturn("mock said")
13var words = mock.say()
14// then
15        Mockito.verify(mock).say()
16        assertTrue(words == "mock said")
17
18// spy
19        val setting = Mockito.withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS)
20        val spy = spy(Abstract1::class.java)
21        Mockito.`when`(spy.say()).thenReturn("spy said")
22        words = spy.say()
23        Mockito.verify(spy).say()
24        assertTrue(words == "spy said")
25    }
26    @Test @SmallTest //测试有构造参数的 abstract 类,这时spy⽆法通过
27    fun test_mock_abstract_args(){
28// spy
29        // val spy = spy(Abstract2::class.java) // error,⽆法spy
30        val setting = Mockito.withSettings().useConstructor("args").defaultAnswer(CALLS_REAL_METHODS)
31        val spy = k(Abstract2::class.java,setting)
32        Mockito.`when`(spy.say()).thenReturn("spy said")
33        val words = spy.say()
34        Mockito.verify(spy).say()
35        assertTrue(words == "spy said")
36    }
37    @Test @SmallTest //测试有构造参数的 inner abstract 类
38    fun test_mock_abstract_inner(){
39abstract class Abstract3(var name: String)  { fun say() = "said" }
40// spy
41        val setting = Mockito.withSettings().useConstructor("inner")/*.outerInstance(outerInstance)*/.defaultAnswer(CALLS_REAL_METHODS)
42        val spy = k(Abstract3::class.java,setting)
43        Mockito.`when`(spy.say()).thenReturn("inner said")
44        val words = spy.say()
45        Mockito.verify(spy).say()
46        assertTrue(words == "inner said")
47    }
48 }
3.打桩静态⽅法
3.1 要求
使⽤
java要使⽤ try-with-resources 语法,kotlin可使⽤use()
3.2 ⽰例
java 代码:
1 @RunWith(AndroidJUnit4.class)
2public class MockitoJava {
3public static int value() { return -1;}
4
5    @Test @SmallTest
6public void testMockStatic(){
7        assertTrue(-1 == MockitoJava.value());
8try(MockedStatic mock = kStatic(MockitoJava.class)) {
9            mock.when(MockitoJava::value).thenReturn(100);
10            assertTrue(100 == MockitoJava.value());
11//超出范围后结束
12        }
13        assertTrue(-1 == MockitoJava.value());
14    }
15 }
kotlin 暂时不⽀持
1    @Test @SmallTest
2    fun test_mock_static2(){
3// given
4        kStatic(StuStatic1::class.java).use {
5// when
6            Mockito.`when`(StuStatic1.value1()).thenReturn(200  )
7// then
8            assertTrue(StuStatic1.value1() == 200 )
9
10            it
11        }
12    }
android模拟点击
4.临时打桩构造函数
  ⽤kConstruction()临时打桩构造函数,在它的作⽤域内,new出来的对象都是模拟对象。
4.1 要求
使⽤
java要使⽤ try-with-resources 语句,kotlin可使⽤use()
4.2 java⽰例
1 @RunWith(AndroidJUnit4.class)
2public class MockitoJava {
3    @Test @SmallTest
4public void testConstruction(){
5class Student { public int run() { return1;} }
6
7        assertTrue(new Student().run() == 1 );
8        try(MockedConstruction mocked = kConstruction(Student.class)){
9            Student stu = new Student();
10            assertTrue(stu.run() == 0  );      //0,not 1
11            Mockito.when(stu.run()).thenReturn(10);
12            assertTrue(stu.run() == 10  );
13        }
14        assertTrue(new Student().run() == 1  ); //ok
15    }
16 }
第8-13⾏是个临时作⽤域,使⽤了java的try-with-resources 语法
使⽤kConstruction⽣成了⼀个MockedConstruction对象。
在第8-13⾏内,new 的student对象都是模拟对象,且可打桩(第11⾏)。
第10⾏模拟对象默认是返回0值的。
4.3 kotlin⽰例
1    @Test @SmallTest
2    fun test_mocking_construction(){
3// given
4        open class Student{ fun run() = 1 fun stop() = 2}
5
6        kConstruction(Student::class.java).use {
7            val student = Student()
8            assertTrue(student.run() == 0 )  //ok
9            `when`(student.run()).thenReturn(10)
10            assertTrue(student.run() == 10)
11        }
12        assertTrue(Student().run  () == 10)  //failed
13    }
  结果同4.2
5.kotlin 拓展库
5.1 引⼊扩展库
testImplementation "kito.kotlin:mockito-kotlin:4.0.0"
  扩展库最新版本可在github上,不是在mockito官⽹上.它可能⽐mockito库更新的慢。
5.3 简单⽰例
1 @RunWith(AndroidJUnit4::class)
2class MockitoKotlin {
3    @Test @SmallTest
4    fun mockito_kotlin_test_mock(){
5        open class Student{ fun value() = 1}
6        val mock = mock<Student>{
7            on { value() } doReturn(10)
8        }
9        assertTrue(mock.value() == 10)
10
11        val spy = spy<Student>{
12            on(it.value()).thenReturn(10)
13        }
14        assertTrue(spy.value() == 10)
15        set(spy)
16        assertTrue(spy.value() == 1 )
17    }
18    @Test @SmallTest
19    fun mockito_kotlin_test_doNothing(){
20        open class Student(var v : Int = -1) {
21            fun value(){
22                println("kotlin doNothing")
23            }
24        }
25        val mock = mock<Student> {
26            doNothing().`when`(it).value()
27        }
28        mock.value()
29        verify(mock).value()
30    }
31 }
  使⽤ on .. thenReturn 对应 henReturn
5.4 更多⽰例
5.4.1 mock
1    @Test
2    fun propertyClassVariable() {
3/* When */
4        propertyClassVariable = mock()
5
6/* Then */
7        expect(propertyClassVariable).toNotBeNull()
8    }
9
10    @Test
11    fun untypedVariable() {
12/* When */
13        val instance = mock<MyClass>()
14
15        expect(instance).toNotBeNull()
16    }
17
18    @Test
19    fun deepStubs() {
20        val cal: Calendar = mock(defaultAnswer = Mockito.RETURNS_DEEP_STUBS)
21        whenever(cal.time.time).thenReturn(123L)
22        expect(cal.time.time).toBe(123L)
23    }
24
25
26    @Test
27    fun testMockStubbing_lambda() {
28/* Given */
29        val mock = mock<Open>() {
30            on { stringResult() } doReturn "A"
31        }
32
33/* When */
34        val result = mock.stringResult()
35
36/* Then */
37        expect(result).toBe("A")
38    }
5.4.2 spy
1    @Test
2    fun spyInterfaceInstance() {
3/* When */
4        val result = spy(interfaceInstance)
5
6/* Then */
7        expect(result).toNotBeNull()
8    }
9
10    @Test
11    fun spyOpenClassInstance() {
12/* When */
13        val result = spy(openClassInstance)
14
15/* Then */
16        expect(result).toNotBeNull()
17    }
18
19    @Test
20    fun doReturnWithSpy() {
21        val date = spy(Date())
22        doReturn(123L).whenever(date).time
23        expect(date.time).toBe(123L)
24    }
25
26    @Test
27    fun doNothingWithSpy() {
28        val date = spy(Date(0))
29        doNothing().whenever(date).time = 5L
30        date.time = 5L
31        expect(date.time).toBe(0L)
32    }
33
34    @Test(expected = IllegalArgumentException::class)
35    fun doThrowWithSpy() {
36        val date = spy(Date(0))
37        doThrow(IllegalArgumentException()).whenever(date).time
38        date.time
39    }
40
41    @Test
42    fun doCallRealMethodWithSpy() {
43        val date = spy(Date(0))
44        doReturn(123L).whenever(date).time
45        doCallRealMethod().whenever(date).time
46        expect(date.time).toBe(0L)
47    }
48
49    @Test
50    fun doReturnWithDefaultInstanceSpyStubbing() {
51        val timeVal = 12L
52
53        val dateSpy = spy<Date> {
54            on { time } doReturn timeVal
55        }
56
57        expect(dateSpy.time).toBe(timeVal)
58    }
59
60    @Test
61    fun doReturnWithSpyStubbing() {
62        val timeVal = 15L
63
64        val dateSpy = spy(Date(0)) {
65            on { time } doReturn timeVal
66        }
67
68        expect(dateSpy.time).toBe(timeVal)
69    }
70
71    @Test
72    fun passAnyStringToSpy() {
73/* Given */
74        val my = spy(MyClass())
75
76/* When */
77        doReturn("mocked").whenever(my).foo(any()) 78
79/* Then */
80        expect(my.foo("hello")).toBe("mocked")
81    }
5.4.3 Matchers
1    @Test
2    fun anyString() {
3        mock<Methods>().apply {
4string("")
5            verify(this).string(any())
6        }
7    }
8
9    @Test
10    fun anyInt() {
11        mock<Methods>().apply {
12int(3)
13            verify(this).int(any())
14        }
15    }
16
17    @Test
18    fun anyClosedClass() {
19        mock<Methods>().apply {
20            closed(Closed())
21            verify(this).closed(any())
22        }
23    }
24
25    @Test
26    fun anyIntArray() {
27        mock<Methods>().apply {
28            intArray(intArrayOf())
29            verify(this).intArray(any())
30        }
31    }
32
33    @Test
34    fun anyClassArray() {
35        mock<Methods>().apply {
36            closedArray(arrayOf(Closed()))
37            verify(this).closedArray(anyArray())
38        }
39    }
40
41    @Test
42    fun anyNullableClassArray() {
43        mock<Methods>().apply {
44            closedNullableArray(arrayOf(Closed(), null))
45            verify(this).closedNullableArray(anyArray())
46        }
47    }
48
49    @Test

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。