最近面試的問題,主要是測試對單元測試中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;
}
}
沒有留言:
張貼留言