假設您有以下課程:
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 需要是易失的而不是最終的,但在一般情況下..是的)
- 在每個測驗用例中創建 RepositoryImpl 而不是使用 @InjectMocks 或 @Before
- 創建兩個嵌套測驗類 - 一個用于初始化邏輯,一個用于核心邏輯
- 不知何故使用@InjectMocks,但僅在一項測驗中重新初始化,不確定是否可能
- get() 中的一些惰性方法,但在一般情況下也破壞了不變性
對我來說,選項 3 似乎很干凈,但也許有更好的方法或需要進一步重構 idk。任何建議都受到高度贊賞。
請注意,我不能只在 Persistence 中使用 @Cachable,因為這不是 Spring 專案。
uj5u.com熱心網友回復:
- 在每個測驗用例中創建 RepositoryImpl 而不是使用 @InjectMocks 或 @Before
- 創建兩個嵌套測驗類 - 一個用于初始化邏輯,一個用于核心邏輯
我認為上述選項是可行的解決方案,但您在這里提出了一個很好的觀點:
- 不知何故使用@InjectMocks,但僅在一項測驗中重新初始化,不確定是否可能
為了實作這一點,您可以簡單地忽略存盤在帶有注釋的測驗類欄位中的實體@InjectMocks
并創建一個單獨的實體,就在這個測驗中(如您提出的第二種方法中所述)。
@ExtendWith(MockitoExtension.class)
class RepositoryTest {
@Mock
Persistence persistence;
@InjectMocks
RepositoryImpl repository;
@Test
void oneOfMultipleTests() {
// here you're defining the persistence field mock behavior
// and using the repository field
}
@Test
void objectNotFound() {
var emptyPersistence = mock(Persistence.class);
when(emptyPersistence.get()).thenThrow(...);
var emptyBasedRepository = new RepositoryImpl(emptyPersistence);
assertNotNull(emptyBasedRepository);
verify(emptyPersistence).persist(argThat(...));
// assert something else if you want
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/508588.html