Robolectric / Mockito给出错误'when()需要一个参数,该参数必须是'模拟的方法调用',但它是一个模拟物

问题描述 投票:0回答:1
实际上,问题比标题更奇怪。我有两个测试,但看不到它们之间的区别。在一个我做

when(context.getPackageManager()).thenReturn(packageManager);

并且工作正常。我在另一个地方做同样的事情,但出现错误。

这是成功的测试:

@RunWith(RobolectricTestRunner.class)

@@ LooperMode(LooperMode.Mode.PAUSED)@Config(sdk = Build.VERSION_CODES.P)公共类BtScannerMockTests{@规则公共MockitoRule mockitoRule = MockitoJUnit.rule()。strictness(Strictness.LENIENT);

@Mock BluetoothAdapter bluetoothAdapter; @Mock BluetoothLeScanner bluetoothLeScanner; @Mock PackageManager packageManager; @Mock Context context; @Before public void setUp() throws Exception { ShadowLog.stream = System.out; } private void setUpMocksForAdapter() { BtScanner.testBtleSupport = true; AndroidBtManager.setBluetoothAdpater(bluetoothAdapter); when(bluetoothAdapter.isEnabled()).thenReturn(true); when(bluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_ON); when(bluetoothAdapter.getBluetoothLeScanner()).thenReturn(bluetoothLeScanner); when(context.getPackageManager()).thenReturn(packageManager); when(packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)).thenReturn(true); } private long startTime = 0; private long time = 0; private ScannerCountDownLatch countDownLatch; private int btDiscoveryTime; private int btleScanTime; @Test public void testBtScannerCycle_BtleScanlength() throws InterruptedException { StatusEventCallback statusEventCallback = new StatusEventCallback() { @Override public void onStatusEvent(StatusEvent statusEvent, PhdInformation phdInformation) { System.out.println("Status event " + statusEvent.name()); switch(statusEvent) { case BTLE_SCAN_STARTED: startTime = System.currentTimeMillis(); break; case CLASSIC_SCAN_STARTED: time = System.currentTimeMillis() - startTime - btleScanTime; startTime = System.currentTimeMillis(); countDownLatch.countDown(); break; } } }; btDiscoveryTime = 1000; btleScanTime = 10000; Context context = ApplicationProvider.getApplicationContext(); setUpMocksForAdapter(); AndroidBtManager.setStatusEventCallback(statusEventCallback); BtScanner.setScanTimes(btDiscoveryTime, btleScanTime); BtScanner btScanner = new BtScanner(context, bluetoothAdapter); startTime = System.currentTimeMillis(); countDownLatch = new ScannerCountDownLatch(2); btScanner.start(); shadowOf(Looper.getMainLooper()).idle(); if(countDownLatch.await(15, TimeUnit.SECONDS)) // Assert length of btle scan time 1 { assertTrue((time > -50 && time < 50)); countDownLatch = new ScannerCountDownLatch(1); if(countDownLatch.await(15, TimeUnit.SECONDS)) // Assert length of btle scan time 2 { assertTrue((time > -50 && time < 50)); } else // Timeout { fail(); } } else // Timeout { fail(); } btScanner.terminateScan(); assertFalse(btScanner.isBtScannerRunning()); }

测试有点复杂,但是重要的是在'setUpMocksForAdapter()'中。它工作正常。失败的测试更加简单,因为它尚未完成并且还没有断言。

@RunWith(RobolectricTestRunner.class) @LooperMode(LooperMode.Mode.PAUSED) @Config(sdk = Build.VERSION_CODES.P) public class ProprietaryDriverMonitorTests { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.LENIENT); @Mock Intent intent; @Mock ResolveInfo resolveInfo1; @Mock ResolveInfo resolveInfo2; @Mock PackageManager packageManager; @Mock Context context; @Before public void setUp() throws Exception { ShadowLog.stream = System.out; context = ApplicationProvider.getApplicationContext(); ContinuaHandlerThread.isUnitTesting = true; } private List<ResolveInfo> matches = new ArrayList<>(); @Test public void testBasicCycle() throws Exception { setUp(); matches.clear(); matches.add(resolveInfo1); matches.add(resolveInfo2); when(context.getPackageManager()).thenReturn(packageManager); when(packageManager.queryIntentServices(intent, 0)).thenReturn(matches); //resolveInfo1.serviceInfo.packageName AndroidBtManager androidBtManager = new AndroidBtManager(context, false, false, true); ProprietaryDriverMonitor proprietaryDriverMonitor = new ProprietaryDriverMonitor(androidBtManager, context, 5); proprietaryDriverMonitor.start(); Thread.sleep(20000); }

[当我执行“(context.getPackageManager())。thenReturn(packageManager);时,此测试会给出失败信息我看不到为什么这个测试失败了,而另一个测试没有失败。我在测试2中做错了什么而在测试1中做错了吗?
android unit-testing robolectric
1个回答
0
投票
我想带Robolectric的cks子不是热门话题。无论如何,答案都是该模拟(在这种情况下为Context)被生成该上下文的另一个调用覆盖。该上下文的初始Mock会保留下来,直到覆盖它的调用为止。在一个测试中,覆盖调用是在给定检查之前进行的,而在另一种情况下,则在之后进行。

在复杂的单元测试中很难看到,但是当涉及到蓝牙连接时,很难编写简单的单元测试。我发现无法测试某些功能,因为Android或库会覆盖我在测试过程中需要执行的任何Mock。

© www.soinside.com 2019 - 2024. All rights reserved.