1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.lifecycle
18 
19 import androidx.kruth.assertThat
20 import androidx.lifecycle.viewmodel.CreationExtras
21 import kotlin.test.fail
22 import org.junit.Test
23 
24 class NewInstanceFactoryTest {
25 
26     @Test
create_withConstructorWithZeroArguments_returnsViewModelnull27     fun create_withConstructorWithZeroArguments_returnsViewModel() {
28         val modelClass = TestViewModel1::class
29         val factory = ViewModelProvider.NewInstanceFactory()
30 
31         val viewModel = factory.create(modelClass, CreationExtras.Empty)
32 
33         assertThat(viewModel).isNotNull()
34     }
35 
36     @Test
create_withConstructorWithOneArgument_throwsNoSuchMethodExceptionnull37     fun create_withConstructorWithOneArgument_throwsNoSuchMethodException() {
38         val modelClass = TestViewModel2::class
39         val factory = ViewModelProvider.NewInstanceFactory()
40         try {
41             factory.create(modelClass, CreationExtras.Empty)
42             fail("Expected `IllegalArgumentException` but no exception has been throw.")
43         } catch (e: RuntimeException) {
44             assertThat(e).hasCauseThat().isInstanceOf<NoSuchMethodException>()
45             assertThat(e)
46                 .hasMessageThat()
47                 .contains("Cannot create an instance of class ${TestViewModel2::class.java.name}")
48         }
49     }
50 
51     @Test
create_withPrivateConstructor_throwsIllegalAccessExceptionnull52     fun create_withPrivateConstructor_throwsIllegalAccessException() {
53         val modelClass = TestViewModel3::class
54         val factory = ViewModelProvider.NewInstanceFactory()
55         try {
56             factory.create(modelClass, CreationExtras.Empty)
57             fail("Expected `IllegalArgumentException` but no exception has been throw.")
58         } catch (e: RuntimeException) {
59             assertThat(e).hasCauseThat().isInstanceOf<IllegalAccessException>()
60             assertThat(e)
61                 .hasMessageThat()
62                 .contains("Cannot create an instance of class ${TestViewModel3::class.java.name}")
63         }
64     }
65 
66     @Test
create_withAbstractConstructor_throwsInstantiationExceptionnull67     fun create_withAbstractConstructor_throwsInstantiationException() {
68         val modelClass = ViewModel::class
69         val factory = ViewModelProvider.NewInstanceFactory()
70         try {
71             factory.create(modelClass, CreationExtras.Empty)
72             fail("Expected `IllegalArgumentException` but no exception has been throw.")
73         } catch (e: RuntimeException) {
74             assertThat(e).hasCauseThat().isInstanceOf<InstantiationException>()
75             assertThat(e)
76                 .hasMessageThat()
77                 .contains("Cannot create an instance of class ${ViewModel::class.java.name}")
78         }
79     }
80 
81     class TestViewModel1 : ViewModel()
82 
83     class TestViewModel2(val unused: Int) : ViewModel()
84 
85     private class TestViewModel3 : ViewModel()
86 }
87