我有一個實現Runnable
的類,名爲DoThingInALoop
。它被賦予第二個類,它將創建一個線程,稱爲線程Boss
。 Boss
可以告訴runnable退出並讓線程終止。之後,它可以創建一個與此相同的新線程DoThingInALoop
。用Mockito模擬創建線程Runnable
當我爲Boss
編寫單元測試時,我想模擬DoThingInALoop
,因爲它不是被測對象。但是,DoThingInALoop
擴展了Loop
類,並且Loop
的代碼實際上正在由Boss
產生的線程中執行。該代碼當然會運行到NullPointerException
,因爲沒有設置成員變量,因爲該對象被模擬。
如何防止Java的Thread
「看透」模擬?
public class Loop implements Runnable {
private final Object member = new Object();
public final void run() {
// This code runs, but it shouldn't
synchronized (member) { // Throws NPE
...
}
// Hook for subclasses
try {
subclassRun();
} finally {
// Mandatory cleanup (unrelated to question)
}
}
public class DoThingInALoop extends Loop {
public void subclassRun() { ... }
public void stopDoingThingsInALoop() {
// Set instance member that on next loop iteration signals thread to return
}
}
public class Boss {
private final DoThingsInALoop toBeMocked;
public Boss(final DoThingsInALoop toBeMocked) {
this.toBeMocked = toBeMocked;
}
public void start() {
// Simplified
new Thread(toBeMocked).start();
}
public void stop() {
toBeMocked.stopDoingThingsInALoop();
}
}
public class TestClass {
@Test
public void aTest() {
// Setup Mocks
DoThingsInALoop mockLoop = mock(DoThingsInALoop.class);
Boss boss = new Boss(mockLoop);
// Run test
boss.start();
// After the above line runs, a new thread is started and
// the run() method of `Loop` executes until the NPE
// is hit when it attempts to access a member variable
// which is of course not set because it is a mocked object
...
}
}
請發佈一些重複性。 'Loop#run'不會被調用。一些虛假的'DoThingInALoopProxyClass#run'將被調用,它將不會執行任何操作。 –
除非你的'run'方法實際上是'final' ... –
你是否在你的模擬中使用了'run()'方法來嘗試? 'doNothing()。when(mockLoop).run();' – Ruben