最近面試的問題,主要是測試對單元測試中mock的概念及依賴注入替換物件的概念。
題目如下,請問如何測試addTenWithRandom()中忽略隨機值的結果?
package com.abc.demo;
import java.util.Random;
public class DemoService {
public int addTenWithRandom(int i) {
return i + 10 + new Random().nextInt();
}
}
這方法測試的困難在於new Random().nextInt()的值是不固定的,所以測試此方法就必須忽略其產生的隨機值,那該如何修改使其變得可測呢?
可設計一個介面RandomInterface並提供產生隨機數的方法nextInt()。
RandomInterface
package com.abc.demo;
public interface RandomInterface {
int nextInt();
}
設計一個類別RealRandom實作RandomInterface對new Random().nextInt()進行包裝。
RealRandom
package com.abc.demo;
import java.util.Random;
public class RealRandom implements RandomInterface {
@Override
public int nextInt() {
return new Random().nextInt();
}
}
設計一個mock類別MockRandom實作RandomInterface,在此即可決定nextInt()回傳的random值。
MockRandom
package com.abc.demo;
public class MockRandom implements RandomInterface {
@Override
public int nextInt() {
return 0;
}
}
原程式中不要直接使用Random.nextInt()取得隨機值,改為使用成員RandomInterface的nextInt()來取得。RandomInterface的實例在建構DemoService時傳入,此即為依賴注入。
DemoService
package com.abc.demo;
public class DemoService {
private RandomInterface random;
public DemoService(RandomInterface random) {
this.random = random;
}
public int addTenWithRandom(int i) {
return i + 10 + random.nextInt();
}
}
在測試程式DemoServiceTests中可替換DemoService的成員RandomInterface為MockRandom來測試。
DemoServiceTests
package com.abc.demo;
public class DemoServiceTests {
public static void main(String[] args) {
new DemoServiceTests().testAddTenWithRandomIgnoreRandomValue();
}
public void testAddTenWithRandomIgnoreRandomValue() {
DemoService demoService = new DemoService(new MockRandom());
assert demoService.addTenWithRandom(10) == 20;
}
}
沒有留言:
張貼留言