假设您有下列类别:
public class RepositoryImpl implements Repository {
private static final Object DEFAULT_OBJECT = new Object();
private final Persistence persistence;
private volatile Object cachedObject; // maybe ignore that this is volatile and non-final
public RepositoryImpl(Persistence persistence) {
this.persistence = persistence;
this.cachedObject = getInitialCachedObject();
}
private Object getInitialCachedObject() {
try {
return persistence.get();
} catch (ObjectNotFoundException e) {
persistence.persist(DEFAULT_OBJECT);
return DEFAULT_OBJECT;
}
}
public Object update() { /*some logic*/ }
public Object get() { /*some logic*/ }
public Object delete() { /*some logic*/ }
}
然后,我想对Repository类进行单元测试,并模拟持久性。我想大概有2个测试来测试初始化逻辑(快乐路径和异常),还有3个测试来测试公共方法。
问题是我应该如何进行测试?
我设法想到的可能选项有:
- 考虑在ctor之后通过公共方法从外部调用初始化
- 打破了不变性(在我的特殊情况下,这已经打破了,因为cachedObject需要是volatile而不是final,但在一般情况下..是的)
- 在每个测试用例中创建RepositoryImpl,而不是使用@InjectMocks或@Before
- 创建两个嵌套测试类-一个用于init逻辑,一个用于核心逻辑
- 以某种方式使用@InjectMocks,但仅在一次测试中重新初始化,不确定是否可能
- get()中的一些懒惰方法,但也打破了一般情况下的不变性
对我来说,选项3看起来很干净,但也许有一个更好的方法,或者需要进一步的重构idk。任何建议都是非常感谢的。
注意,我不能在持久性中使用@Cachable,因为这不是一个Spring项目。
1条答案
按热度按时间i7uq4tfw1#
1.在每个测试用例中创建RepositoryImpl,而不是使用@InjectMocks或@Before
1.创建两个嵌套测试类-一个用于init逻辑,一个用于核心逻辑
我认为上述选项是可行的解决方案,但您在这里提出了一个很好的观点:
1.以某种方式使用@InjectMocks,但仅在一次测试中重新初始化,不确定是否可能
要实现这一点,只需忽略存储在用
@InjectMocks
标注的测试类字段中的示例,并创建一个单独的示例,就在这个测试中(如第二个建议的方法所述)。