如何测试一个在没有模拟框架的情况下调用其他类中其他方法的方法



我一直在尝试对此方案进行测试,但是找不到测试的好方法。因此,该测试中的此方法创建了某些自定义类型的新对象,该对象以后调用一种方法。初始化。我正在测试我的测试失败的课程和课程之间没有关系。没有任何模拟框架,就可以进行测试。我也无法更改源代码。如果是不良的代码,我仍然可以对其进行测试。

class DocuSigRESTProvider{
 public IDocumentSet sendDocuments() {
 /// code...
 ITransformer transformer = new SendDocumentsRESTTransformer();
 ITransformerResult result = transformer.transformRequest(args);
 }
}

当代码进入transformrequest((时,它由于某些字段而炸毁。它总是创建一个新的,因此即使在我的测试类中我创建了一个senddocumentRestTransformer的实例,它也不会在运行时找到要初始化的特定字段。

junit

private SendDocumentsRESTTransformer sendDocumentRESTTransfomer;
private ITransformerResult iTransformerResult;   
sendDocumentRESTTransfomer = mock( SendDocumentsRESTTransformer.class );
iTransformerResult = mock( ITransformerResult.class );
@Test
public void testSendDocuments() throws Exception {
    DocusignRESTProvider docusignRestProvider = new DocusignRESTProvider();
    docusignRestProvider.setLoggingHandler( iloggingHandler );
    docusignRestProvider.setDocumentManager( iDocumentManager );
    docusignRestProvider.setConfiguration( iProviderConfiguration );
    docusignRestProvider.setManager( idocTranManager );
    docusignRestProvider.setEmailProcessor( emailProcessor );
    List<IDocumentDto> iDocumentDtoList = new ArrayList<>();
    iDocumentDtoList.add( iDocumentDto );
    List<IDocument> iDocumentList = new ArrayList<>();
    iDocumentList.add( iDocument );
    when( restProvider.loadDocuments( iClientUserDto, iDocumentSet ) ).thenReturn( iDocumentDtoList );
    when( iDocumentSet.getDocuments() ).thenReturn( iDocumentList );
    when( restProvider.validateDocs( anyListOf( IDocument.class ), anyListOf( IDocumentDto.class ) ) ).thenReturn( iDocumentDtoList );
    PowerMockito.whenNew( SendDocumentsRESTTransformer.class ).withAnyArguments().thenReturn( sendDocumentRESTTransfomer );
    when( sendDocumentRESTTransfomer.transformRequest( any( ITransformerArgs.class ) ) ).thenReturn( iTransformerResult );
    iDocumentSet = docusignRestProvider.sendDocuments( iClientUserDto, iDocumentSet );
    assertNotNull( iDocumentSet );
}

此代码可以测试吗?

您可以创建一个setter方法来注入外部依赖关系。这样的东西。

class DocuSigRESTProvider{
 private ITransformer transformer = new SendDocumentsRESTTransformer();
 public IDocumentSet sendDocuments() {
   /// code...
   ITransformerResult result = transformer.transformRequest(args);
 }
  //package level method
 void setTransformer(ITransformer transformer) {
    this.transformer = transformer
 }
}

然后您可以从测试类中注入stub对象。

@Test
public void myTest() {
  DocuSigRESTProvider docusignRestProvider = new DocuSigRESTProvider();
  docusignRestProvider.setTransformer(new SendDocumentsRESTTransformerStub());
  //...rest of test code.
}
private class SendDocumentsRESTTransformerStub extends SendDocumentsRESTTransformer {
  //... Override methods.
}

必须以某种方式编写一般代码,才能进行单位测试。您不能只采用任何(任意的(代码并以干净的方式进行测试。

因此,您应该遵守一些惯例/遵循一些实践。提供的代码片段并没有真正遵循这些实践,因此您被迫使用PowerMock,只有在绝对没有其他选择的情况下,才能使用PowerMock(如果有的话(。我个人尝试避免尽可能多地使用Power Mock。

第一个经验法则是使用依赖项注入,而不是使用new关键字在方法中创建对象。

所以让我们稍微更改您的代码:

class DocuSigRESTProvider{
  private ITransformer transformer;
  public DocuSigRESTProvider(ITransformer transformer) {
     this.transformer = transformer;
  }
  public IDocumentSet sendDocuments() {
     /// code...
     ITransformerResult result = transformer.transformRequest(args);
  }
}

那么我们实际上获得了什么?很多事情:DocuSigRESTProvider类并不涉及创建ITRansFormer实现(的确为什么要打扰,它应该宁愿获得接口并对其进行使用(。界面实现是从外部注入(请阅读有关构造仪注入,设置器注入等等,我不会潜入依赖性注入,因为它本身就是一个广泛的话题(。

(。

因此,应该检查"代码"部分中写的内容(毕竟您检查了sendDocuments方法(,直到您到达最后一行,这是变压器调用。

现在您确实想模拟/固执变压器,但是这次(这是一个重大的改进!(您应该模拟界面而不是真实的实现。使用这种方法,您可以使用EasyMock/Mockito-它们都可以为接口创建模拟,甚至可以根据需要制作自己的"假"实现。

相关内容

最新更新