我在模拟一个模拟方法时得到NPE
。我的理解是只要我们使用模拟对象调用方法,mock就会处理其他所有事情。
待测方法
public IDocumentSet sendDocuments(IClientUserDto cu, IDocumentSet ds) throws ESignatureProviderException {
logMethodStartDebug(cu, CLASS_NAME, "sendDocuments(IClientUserDto, IDocumentSet)");
IDocumentSet set = null;
List<DocumentContent> documentContent = new ArrayList<DocumentContent>();
Envelope env = new Envelope();
MultiPart multiPart = new MultiPart();
String token = null;
String envId = null;
String status = null;
try {
List<IDocumentDto> dtos = loadDocuments(cu, ds);
List<IDocument> docs = ds.getDocuments();
dtos = validateDocs(docs, dtos);
ISendDocumentsTransformerArgs args = new SendDocumentsTransformerArgs(cu);
args.setDocuments(docs);
args.setDocumentDtos(dtos);
args.setCallbackConfiguration(getConfiguration().getCallback());
args.setModuleConfiguration(getModuleConfiguration());
ITransformer transformer = new SendDocumentsRESTTransformer();
ITransformerResult result = transformer.transformRequest(args);
JUnit测试用例
@RunWith( PowerMockRunner.class )
@PrepareForTest( {DtoUtils.class, ESignatureSpringUtil.class, AppContext.class, DocusignRESTUtil.class} )
public class TestDocusignRESTProvider {
private String accountId = "025f1a5d-b796-4ba6-85d2-b2a4a90d109c";
private String address;
private IClientUserDto iClientUserDto;
private IClientUserVendorDto iClientUserVendorDto ;
private ILoggingHandler iloggingHandler;
private ApplicationContext applicationContext;
private DocusignRESTClient docusignRestClient;
private WebTarget webTarget;
private Response response;
private Invocation.Builder builder;
private IDocumentSet iDocumentSet;
private IDocumentManager iDocumentManager;
private IProviderConfiguration iProviderConfiguration;
private ITransformer iTransformer;
private ITransformerResult iTransformerResult;
private IManager iManager;
private SendDocumentsTransformerArgs args;
@Before
public void setUp() throws Exception {
iClientUserDto = new ClientUserDto();
iloggingHandler = mock( ILoggingHandler.class );
applicationContext = mock( ApplicationContext.class );
iClientUserVendorDto = mock( IClientUserVendorDto.class );
docusignRestClient = mock( DocusignRESTClient.class );
webTarget = mock( WebTarget.class );
response = mock( Response.class );
builder = mock( Invocation.Builder.class );
iDocumentSet = mock( IDocumentSet.class );
iDocumentManager = mock( IDocumentManager.class );
iProviderConfiguration = mock( IProviderConfiguration.class );
iTransformer = mock( ITransformer.class );
iTransformerResult = mock( ITransformerResult.class );
iManager = mock( IManager.class );
args = mock( SendDocumentsTransformerArgs.class );
PowerMockito.mockStatic( DtoUtils.class );
PowerMockito.mockStatic( ESignatureSpringUtil.class );
PowerMockito.mockStatic( AppContext.class );
PowerMockito.mockStatic( DocusignRESTUtil.class );
}
@Test
public void testSendDocuments() throws Exception {
AppContext.setApplicationContext( applicationContext );
IClientUserDto iClientUserDto = mock( IClientUserDto.class );
DocusignRESTProvider docusignRestProvider = new DocusignRESTProvider();
docusignRestProvider.setLoggingHandler( iloggingHandler );
docusignRestProvider.setDocumentManager( iDocumentManager );
docusignRestProvider.setConfiguration( iProviderConfiguration );
docusignRestProvider.setManager( iManager );
Mockito.when( iloggingHandler.isGeneralDebugEnabled() ).thenReturn( Boolean.TRUE );
Mockito.when( iTransformer.transformRequest( args ) ).thenReturn( iTransformerResult );
docusignRestProvider.sendDocuments( iClientUserDto, iDocumentSet );
}
因此,当代码到达transformer.transformRequest(args);
行时,它会爆炸。我在嘲笑ITransformer并在上面调用transformerRequest方法,不应该给我一个模拟对象,或者我是以错误的方式做这件事。
答案 0 :(得分:1)
你没有嘲笑变形金刚对象。
ITransformer transformer = new SendDocumentsRESTTransformer();
这一行是创建实际对象而不是模拟对象。在调用新的SendDocumentsRESTTransformer()时,您需要指示mockito注入模拟对象。使用PowerMockito执行此操作。
。PowerMockito.whenNew(SendDocumentsRESTTransformer.class).withNoArguments()thenReturn(iTransformer);
在调用
之前在测试方法中添加此行docusignRestProvider.sendDocuments( iClientUserDto, iDocumentSet );
这将指示Mockito在调用new SendDocumentsRESTTransformer()
时返回一个模拟对象,因此在sendDocuments
方法变换器中设置为mock对象。
答案 1 :(得分:1)
在这里给你一个完整的答案:我认为你正在走错了兔子洞。
任何需要如此众多测试设置的课程都明显违反了Single Responsibility Principle。
单位测试只有在用于小型,可测试的生产代码单元时才能展现其优势。但是你需要10个以上的模拟,并在4个类中模拟静态方法,以便设置你的测试用例。
这是个人观点,但基于大量经验:此类测试对您没有帮助。您花费小时来编写仅遵循生产代码实施的测试代码。你不会这样找到错误。
只有在必须更改生产代码时才会发现单元测试中断。更糟糕的是:即使是最简单的重构也可能会立即破坏这样的单元测试。在嘲笑静态的东西时,即使是另一个类中不相关的变化,也有可能在其他地方变成失败的单元测试。
这种单元测试对你的工作没有帮助;恰恰相反:他们让你失望。
换句话说:你不应该花时间理解为什么PowerMock会让你失败(因为你在测试用例中做错了)。相反,你应该做两件事之一:
含义:单元测试不是为了达到“100%覆盖率”而编写的,也不是为了在某些“有单元测试”电子表格中加上勾选标记。
编写它们是为了验证您的代码;帮助您找到并修复错误。也许我错了;但是你在这里展示的东西看起来并不像任何属于“有用”类别的东西。
答案 2 :(得分:0)
你为什么要嘲笑这里使用的所有类?这是错误的,这在Junit中不是一个好习惯。单独模拟服务,不要模拟变压器。让服务返回xml或任何对象进行转换,让变换器完成它的工作。确保模拟对象实际上被模拟了。首次亮相代码并检查对象。我对象没有被嘲笑然后它可能会抛出一个空指针。