测试桩Stub
桩:截断的或非常短的物体。
测试桩,用最简单的可能实现代替Real。
基本实现:所有方法仅一行,返回默认值。
public class LoggerStub implements Logger {public void log(LogLevel level, String message) {// still a no-op}public LogLevel getLogLevel() {return LogLevel.WARN; // hard-coded return value}
}
伪造对象Fake
Fake是Real的简化版本,但是没有副作用。
public interface UserRepository {void save(User user);User findById(long id);User findByUsername(String username);
}public class FakeUserRepository implements UserRepository {private Collection<User> users = new ArrayList<User>();public void save(User user) {if(findById(user.getId()) == null) {users.add(user);}}public User findById(long id) {for(User user : users) {if(user.getId() == id) {return user;}}return null;}public User findByUsername(String username) {for(User user : users) {if(user.getUsername().equals(username)) {return user;}}return null;}
}
测试间谍Spy
Spy是一种测试替身,它用于记录过去发生的情况,测试事后知道所发生的一切。
public class DLog {private final DLogTarget[] targets;public DLog(DLogTarget... targets) {this.targets = targets;}public void write(Level level, String message) {for(DLogTarget each : targets) {each.write(level, message);}}
}public class DLogTest {@Testpublic void writesEachMessageToAllTargets() {SpyTarget spy1 = new SpyTarget();SpyTarget spy2 = new SpyTarget();DLog log = new DLog(spy1, spy2);log.write(Level.INFO, "Hello world.");assertTrue(spy1.received(Level.INFO, "Hello world."));assertTrue(spy2.received(Level.INFO, "Hello world."));}
}// 使用SpyTarget跟踪数据
class SpyTarget implements DLogTarget {private List<String> log = new ArrayList<String>();public void write(Level level, String message) {log.add(concatenated(level, message));}public boolean received(Level level, String message) {return log.contains(concatenated(level, message));}private String concatenated(Level level, String message) {return level.getName() + ":" + message;}
}
模拟对象Mock
Mock是特殊的Spy。它是一个在特定情景下可配置行为的对象。