首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在安卓系统中模拟科特林的kotlinx.android.synthetic视图

如何在安卓系统中模拟科特林的kotlinx.android.synthetic视图
EN

Stack Overflow用户
提问于 2017-10-26 21:41:37
回答 3查看 2.3K关注 0票数 8

我有一个用Kotlin写的片段。我使用导入布局视图

代码语言:javascript
复制
import kotlinx.android.synthetic.main.my_fragment_layout.

在我的一个方法中,我设置了TextView的文本:

代码语言:javascript
复制
fun setViews() {
    myTextView.text = "Hello"
    // In Java I would have used:
    // (getView().findViewById(R.id.myTextView)).setText("Hello");
}

在我的普通JVM单元测试中,我想使用Mockito测试这个方法。例如,如果上面的方法是用java编写的,我可以这样做:

代码语言:javascript
复制
public void setViewsTest() {
    // Mock dependencies
    View view = Mockito.mock(View.class);
    TextView myTextView = Mockito.mock(TextView.class);
    when(fragment.getView()).thenReturn(view);
    when(view.findViewById(R.id. myTextView)).thenReturn(myTextView);

    // Call method
    fragment.setViews();

   // Verify the test
   verify(myTextView).setText("Hello");
}

在使用Kotlin的kotlinx.android.synthetic视图时,我如何实现类似的实现?

EN

回答 3

Stack Overflow用户

发布于 2017-10-27 00:37:02

我认为对于这种类型的测试,Robolectric是一个更合适的工具。使用它,您可以更轻松地在JVM上测试具有Android依赖项的代码。

例如,您的测试将如下所示:

代码语言:javascript
复制
@Test
fun `should set hello`() {
    val fragment = YourFragment()

    fragment.setViews()

    assertEquals(fragment.myTextView.getText().toString(), "Hello");
}
票数 2
EN

Stack Overflow用户

发布于 2018-08-02 17:21:17

我也一直在寻找这个问题的解决方案,这就是我目前正在做的模拟视图,以便能够验证它们。

这个解决方案不使用kotlinx.android.synthetic,因为我还没有找到避免“方法未被模仿”异常的方法,而是使用Butterknife方法。

在活动或片段中:

代码语言:javascript
复制
@BindView(R.id.my_text_view)
internal lateinit var myTextView: TextView
// ...
fun setViews() {
    myTextView.text = "Hello"
}

在测试中:

代码语言:javascript
复制
import com.nhaarman.mockito_kotlin.mock

class MyActivityTest {

    private val underTest = MyActivity()

    @Before
    fun setUp() {
        underTest.myTextView = mock()
    }

    @Test
    fun setViews() {
        underTest.setViews()

        verify(underTest.myTextView).text = "Hello"
    }
}
票数 1
EN

Stack Overflow用户

发布于 2018-09-12 20:05:14

我也有同样的问题。

发现Kotlin extension为视图/片段添加了一些功能。假设-我有Fragment - SampleFragment,其中onViewCreated()我在膨胀后访问一些视图:

代码语言:javascript
复制
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    with(webView) {
        webViewClient = createWebClient()
    }
}

当然,我对webViewClient = createWebClient()的单元测试失败了

那么,让我们看看kotlin扩展添加到了我的片段中(转到Tools-> Kotlin ->Show Kotlin Byte Code,然后选择反编译)。

代码语言:javascript
复制
public final class SampleFragment extends Fragment {
    ...
    private HashMap _$_findViewCache;

    public View _$_findCachedViewById(int var1) {
      if (this._$_findViewCache == null) {
         this._$_findViewCache = new HashMap();
      }

      View var2 = (View)this._$_findViewCache.get(var1);
      if (var2 == null) {
         View var10000 = this.getView();
         if (var10000 == null) {
             return null;
         }

         var2 = var10000.findViewById(var1);
         this._$_findViewCache.put(var1, var2);
      }

      return var2;
   }

现在,我们有了存储所有ids的HashMap ->Views键值对。有两种可能的解决方案: 1.窥探你的对象并返回正确的视图:

代码语言:javascript
复制
@Mock lateinit var view: View
@Mock lateinit var webView: WebView

@Before
fun setUp() {
    sampleFragment = spy(SampleFragment())
    doReturn(view).`when`(sampleFragment).view
    doReturn(webView).`when`(view).findViewById<WebView>(R.id.webView)
}

  1. 使用反射(模拟白盒)来初始化_$_findViewCache HashMap。

var hashMap = java.util.HashMap() hashMap.put(R.id.webView,webView) Whitebox.setInternalState(sampleFragment,"_\$_findViewCache",hashMap)

也许有另一种更特定于Kotlin的方法来避免这个问题?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46955978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档