Reputation: 857
I am getting NPE
while mocking a mocked method. My understanding is that mock takes care of everything else as long as we invoke the method using mocked object.
Method under test
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 test case
@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 );
}
So, when the code reaches transformer.transformRequest(args);
line it blows up. I am mocking the ITransformer and calling transformerRequest method on it, shouldn't that return me a mock object or I am doing it in a wrong way.
Upvotes: 0
Views: 1642
Reputation: 3841
Why are you mocking all the classes used in here? This is wrong and this is not a good practice in Junit. Mock service alone and do not mock transformers. Let the service return the xml or any object to transform and let the transformer do its job.Make sure the mock object is actually getting mocked. Debut the code and inspect the object. I the object is not mocked then it may throw a Null Pointer.
Upvotes: 0
Reputation: 140457
Giving you a complete non-answer here: I think you are going down the wrong rabbit hole.
Any class that needs so many test settings as you are showing here is clearly violating the Single Responsibility Principle.
Unit tests can only unfold their benefits when used for small, testable units of production code. But you need 10+ mocks, and to mock static methods in 4 classes in order to setup your testcases.
This is personal opinion, but based on a lot of experience: such tests do not help you. You spend hours to write test code that simply follows the implementation of your production code. You don't find bugs this way.
You only find that your unit test break whenever you have to change your production code. And worse: even the simplest refactoring might break such unit tests immediately. And when mocking static stuff, even a un-related change in another class has the potential to turn into a failing unit test elsewhere.
Such kind of unit tests do not help your work; to the contrary: they slow you down.
In other words: you shouldn't spend your time understanding why PowerMock is failing you here (because you did something wrong in your testcase). Instead you should do one of two things:
Meaning: unit tests are not written to achieve "100% coverage" or to allow putting a checkmark in some "has a unit test" spreadsheet.
They are written to verify your code; to help you find and fix bugs. And maybe I am wrong; but what you are showing here doesn't look like anything that falls into the "helpful" category.
Upvotes: 1
Reputation: 3564
You are not mocking the transformer object.
ITransformer transformer = new SendDocumentsRESTTransformer();
This line is creating actual object and not mock object. You need to instruct mockito to inject a mock object when new SendDocumentsRESTTransformer() is called. Use PowerMockito to do this.
PowerMockito.whenNew(SendDocumentsRESTTransformer.class).withNoArguments().thenReturn(iTransformer);
Add this line in the test method before calling
docusignRestProvider.sendDocuments( iClientUserDto, iDocumentSet );
This will instruct Mockito to return a mock object when new SendDocumentsRESTTransformer()
is called thus inside your sendDocuments
method transformer is set to mock object.
Upvotes: 1