簡體   English   中英

Mockito.spy 對象未被識別

[英]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 庫中的mockspy方法之間的區別。

使用mock ,類的整個行為都由 Mockito 處理,這就是我們使用Class參數調用它的原因:

FirstClass firstObject = mock(FirstClass.class);
SecondClass secondObject = mock(SecondClass.class);

沒有創建FirstClassSecondClass實際實例。

當使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM