[英]Mockito.spy object is not being recognized
我正在嘗試測試以下方法:
@Override
public Target apply(Source source) throws MappingException {
try {
Target target = targetModelObjectFactory.create(Target.class);
mapNameToFirstName(source, target);
mapMailToEMail(source, target);
mapSourceSubEntityToTargetSubEntity(source, target);
mapPrimitiveSourceColToPrimitiveTargetCol(source, target);
mapSubEntitiesSourceColToSubEntitiesTargetCol(source, target);
mapSourceSubEntityFieldToSubEntityFetchedField(source, target);
produceProducedFieldValue(target);
setConstantFieldConstantValue(target);
return target;
} catch (Exception e) {
throw new MappingException(source, e);
}
}
這是我測試的一部分:
public void TestApply() throws MappingException, MappingOperatorCreationException, TargetModelObjectCreationException {
Source mockedSource = Mockito.mock(Source.class);
Target mockedTarget = Mockito.mock(Target.class);
TargetModelObjectFactory targetModelObjectFactory = Mockito.spy(TargetModelObjectFactory.class);
Mockito.when(targetModelObjectFactory.create(Target.class)).thenReturn(mockedTarget);
sourceToTargetMapper.apply(mockedSource);
}
我遇到的問題是這部分:
Target target = targetModelObjectFactory.create(Target.class);
當在應用函數中調試targetModelObjectFactory
值時,我正在測試它的值是“'this'不可用”並且我不斷收到 NullPointerException
targetModelObjectFactory
是一個接口的節點
我一直在嘗試這樣做:
TargetModelObjectFactory targetModelObjectFactory1 = Mockito.mock(TargetModelObjectFactory.class,Mockito.RETURNS_DEEP_STUBS);
但仍然沒有運氣
任何幫助,將不勝感激
問題的主要來源是測試中缺少targetModelObjectFactory
對象的注入。 當您模擬/監視類TargetModelObjectFactory
,您獲得的對象絕不會傳遞給測試類,因此它的引用為空,因此在嘗試調用實際空引用上的方法create
時會拋出NullPointerException
。
根據您測試課程的其余部分(我只能猜測),您可以選擇兩種方法。 第一個是構造函數注入(通常更可取,您可以在此處閱讀更多內容):
class SourceToTargetMapper {
private TargetModelObjectFactory targetModelObjectFactory;
SourceToTargetMapper(TargetModelObjectFactory targetModelObjectFactory) {
this.targetModelObjectFactory = targetModelObjectFactory;
}
}
第二個是字段注入,這要歸功於@ @Inject
、@ @Autowired
等注釋,這取決於所使用的工具:
class SourceToTargetMapper {
@Autowired
private TargetModelObjectFactory targetModelObjectFactory;
}
使用 Mockito 可以輕松處理這兩種情況:
@Test
void constructorInjectionTest() {
TargetModelObjectFactory factory = mock(TargetModelObjectFactory.class);
SourceToTargetMapper mapper = new SourceToTargetMapper(factory);
Source source = mock(Source.class);
Target target = mock(Target.class);
when(factory.create(Target.class))
.thenReturn(target);
Target result = mapper.apply(source);
assertSame(target, result);
}
@Mock
TargetModelObjectFactory factory;
@InjectMocks
private SourceToTargetMapper mapper;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
void fieldInjectionTest() {
Source source = mock(Source.class);
Target target = mock(Target.class);
when(factory.create(Target.class))
.thenReturn(target);
Target result = mapper.apply(source);
assertSame(target, result);
}
另一件值得注意的事情是 Mockito 庫中的mock
和spy
方法之間的區別。
使用mock
,類的整個行為都由 Mockito 處理,這就是我們使用Class
參數調用它的原因:
FirstClass firstObject = mock(FirstClass.class);
SecondClass secondObject = mock(SecondClass.class);
沒有創建FirstClass
和SecondClass
實際實例。
當使用spy
,我們明確地告訴 Mockito,哪些方法應該改變它們的行為,哪些方法應該按照類中的定義實際調用。 我們可以使用Class
參數或實際對象(后者更常用)來創建間諜。 在間諜的情況下,實際行為通常根本不會改變,因為間諜可用於檢查該方法是否被實際調用:
MyClass object = spy(new MyClass());
doStuff(object);
verify(object, times(1))
.myMethod();
在您的情況下,由於您更改了TargetModelObjectFactory
類的行為,因此mock
可能是更好的選擇。
我在 GitHub 上創建了一個存儲庫,您可以在其中找到所有代碼 - 所有測試都通過。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.