Win a copy of Five Lines of Code this week in the OO, Patterns, UML and Refactoring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

Misunderstanding of Null Pointer Exception in unit test

 
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I use Spock for unit testing in Spring Boot Application. Now I am trying to code unit test for service layer methods. As a result I get NullPointer exception. But I don't how it thrown and why.
This is my service method:

And this is the unit test method:

As you see when memberService.getAllMembers() is invoking exception thrown and it shows starting point of exception is memberRepository.findAll() which is in the service method. Why it happens, I don't understand. Actually
I set this memberRepository.findAll() >> mockMembers as a mock in test method, why it returns null inside service.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also, when I change this

to this

the test passed. But little confusing here, how it passed. Because exception was thrown even reaching this line ( I mean "then" block), also aren't they same?:
1 * memberRepository.findAll()
with
memberRepository.findAll()
 
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you post the full stack trace?
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you do this?
Run with --stacktrace option to get the stack trace

You're looking for where it says "caused by" in the stack trace. Show us that.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What does MemberMapper.INSTANCE.entityToDtoList() do when you pass it a null object? Does it throw a NullPointerException?
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think no, it is default implementation of MapStruct. And I checked source code that is generated by MapStruct, it checks for list is null or not.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alright, entityToDtoList(null) returns null. Now let's look at your code to see if that behaviour is handled appropriately:

members is now null. The what do you think is going to happen on your next line of code?
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
isEmpty() method is calling on null object? and it is not possible.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, calling any method on a null object will throw a NullPointerException.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Cooke wrote:Alright, entityToDtoList(null) returns null. Now let's look at your code to see if that behaviour is handled appropriately:


Yes, I agree.
But my question is why here it is null entityToDtoList(null), why memberRepository.findAll() returns null. I set this in test method. And it is not null there, it has mockMembers list and I print it out in test method, it returns what it has to (mockMembers list), but it goes as a null to service method.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Without running your code, which I can't do right now, I'd say it's most likely because you have not instructed the mock memberRepository object to return anything when findAll() method is called. I recommend you double check the syntax for doing that with Spock.

This looks highly suspicious to me, especially the MemberMapper line. It looks like you're defining Spock like instructions on an object that is not a Spock mock object so mockMembers is unlikely to be in the state you expect.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Cooke wrote:Without running your code, which I can't do right now, I'd say it's most likely because you have not instructed the mock memberRepository object to return anything when findAll() method is called. I recommend you double check the syntax for doing that with Spock.


From documentation
Returning Fixed Values
We have already seen the use of the right-shift (>>) operator to return a fixed value:
subscriber.receive(_) >> "ok"


So I think memberRepository.findAll() >> mockMembers is right and that will return fixed mockMembers list

Tim Cooke wrote:
This looks highly suspicious to me, especially the MemberMapper line. It looks like you're defining Spock like instructions on an object that is not a Spock mock object so mockMembers is unlikely to be in the state you expect.


I changed dto to entity object to get rid of that line which you mentioned. Now I just add entity object to list and say memberRepository.findAll() should return that list. But the problem still exist.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm going to need to try a lot of this out so my next reply is more than guesswork. I'll get back to you in a while.
 
Saloon Keeper
Posts: 12133
258
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is there no stack trace at /ms-team/build/reports/tests/test/index.html?
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Is there no stack trace at /ms-team/build/reports/tests/test/index.html?


.../index.html file contains this
 
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not deeply familiar with Spock but I'm curious as to what this does:

The << is a data pipe where data from the source (right hand side) gets piped to the variable on the left hand side. The examples given in the documentation are like so:

That is: a, b, c would be assigned values from the result of the query.

In your code, what does the data being piped get assigned to? Does it take everything in the right hand side and put it into the members array/collection? Have you tried debugging to check that members is not null?
 
Stephan van Hulst
Saloon Keeper
Posts: 12133
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Asif Haciyev wrote:.../index.html file contains this


That's just the HTML to show the test report. If you open it in a browser it should show you the actual test report.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:In your code, what does the data being piped get assigned to? Does it take everything in the right hand side and put it into the members array/collection? Have you tried debugging to check that members is not null?


Yes, it adds object on the right side to the list on the left side. From documentation
class PublisherSpec extends Specification {
   Publisher publisher = new Publisher()
   Subscriber subscriber = Mock()
   Subscriber subscriber2 = Mock()

   def setup() {
       publisher.subscribers << subscriber // << is a Groovy shorthand for List.add()
       publisher.subscribers << subscriber2
   }
}

Yes I did, it is not null. I print it out and it shows that list has objects which I have added.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

Asif Haciyev wrote:.../index.html file contains this


That's just the HTML to show the test report. If you open it in a browser it should show you the actual test report.


I checked it. It is just a test summary, like:
1 test, 1 failure, 0 ignore, 0.879s duration, 0% successful, package and class names.
Similar to "run test with coverage".
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Did you double-check that memberRepository is not null? What does the service constructor look like? Just want to make sure all the basic assumptions are correct.

With that code, we're assuming that the constructor properly sets a memberRepository field.

If that checks out, I would try moving those two lines to given block to see if that makes a difference. I know the setup() block should work but again, I would just want to eliminate these as possible causes.
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Asif Haciyev wrote:also aren't they same?:
1 * memberRepository.findAll()
with
memberRepository.findAll()


My understanding from what I read in the documentation is that the "1 *" causes it to be interpreted as an expected interaction vs. just a plain old method call.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have reproduced this in the Spock Web Console http://meetspock.appspot.com/

Haven't figured out what's up yet, but I'm very curious now.

 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, despite the stub on line 62, the call to entityToDtoList seems to be getting null. Baffling.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:Did you double-check that memberRepository is not null?


Yes, I checked, it is not null. I print it out on console, it shows Mock for type 'MemberRepository' named 'memberRepository'

Junilu Lacar wrote:
What does the service constructor look like? Just want to make sure all the basic assumptions are correct.





With that code, we're assuming that the constructor properly sets a memberRepository field.

If that checks out, I would try moving those two lines to given block to see if that makes a difference. I know the setup() block should work but again, I would just want to eliminate these as possible causes.


I did what you said. I commented out setup() method and moved these two lines to given block. But it didn't make sense
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:My understanding from what I read in the documentation is that the "1 *" causes it to be interpreted as an expected interaction vs. just a plain old method call.


So, in my case I need 1 * memberRepository.findAll() to be sure method is calling at least once. Right?
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Asif Haciyev wrote:

Junilu Lacar wrote:My understanding from what I read in the documentation is that the "1 *" causes it to be interpreted as an expected interaction vs. just a plain old method call.


So, in my case I need 1 * memberRepository.findAll() to be sure method is calling at least once. Right?


That basically says "memberRepository.findAll()" is called exactly one time.

The documentation says if you want "at least one time" you should write
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've only been able to make Tim's test work if I change Mock() to Stub() and remove the interaction check. But that kind of changes the test.

I put in a bunch of checks but the baffling thing is that somehow if you use Mock(), the stubbing gets clobbered when you make the critical call to getAllMembers() -- it seems as if the mocked findAll() method exhibits default behavior of returning null all of a sudden even though you still have the same mock object (I verified this using hashCode())
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even just removing the interaction assertion makes it work ok for me. Makes no sense.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I've only been able to make Tim's test work if I change Mock() to Stub() and remove the interaction check. But that kind of changes the test.


Yes it will work. And I also mentioned that but even not changing Mock() to Stub() test is passing. But I don't know it is right or not. Let's say if I remove the interaction then test will pass, but will it be right test or just method works without exception. Also do I need change Mock() to Stub() actually.

Asif Haciyev wrote:Also, when I change this

to this

the test passed.


Junilu Lacar wrote:I put in a bunch of checks but the baffling thing is that somehow if you use Mock(), the stubbing gets clobbered when you make the critical call to getAllMembers() -- it seems as if the mocked findAll() method exhibits default behavior of returning null all of a sudden even though you still have the same mock object (I verified this using hashCode())


And I am sorry, I didn't get the second part of your answer.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Cooke wrote:Even just removing the interaction assertion makes it work ok for me. Makes no sense.


I also asked same question Junilu. Will it be right test or it is just working without exception?
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I found this old blog post (https://blog.andresteingress.com/2013/10/29/spock-mocking-and-stubbing) and I got Tim's to run like this (see line 21):

 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think this is a better organization (how Tim had it), just because scope of things are minimized to where they're absolutely needed, in particular, the mockMemberEntities list. I also like to add descriptions for the when and then blocks to make it clear this is a white box test:

Edit: and this works as well (I guess it's more "Groovy"):
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't really have a definite explanation of why the change I showed works. I suspect it has something to do with how the dynamic proxies work with mocks that are also stubbed.
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Some food for thought regarding the use of Mocks vs Stubs vs Spies:
https://objectcomputing.com/news/2018/06/22/mock-vs-stub-vs-spy
https://martinfowler.com/articles/mocksArentStubs.html

Here's Tim's test reworked to use a stub (it passes).

To be clear, I'm not saying one is better than the other. I think the important thing is to understand what the intent of the test is and use the most appropriate approach that aligns with the intent.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I figured it out. Turns out the answer was on the very page of documentation referenced by the OP yesterday, just a little further on down Spock: Combining mocking and stubbing.

Mocking and stubbing go hand-in-hand:


When mocking and stubbing the same method call, they have to happen in the same interaction. In particular, the following Mockito-style splitting of stubbing and mocking into two separate statements will not work:


As explained in Where to Declare Interactions, the receive call will first get matched against the interaction in the then: block. Since that interaction doesn’t specify a response, the default value for the method’s return type (null in this case) will be returned. (This is just another facet of Spock’s lenient approach to mocking.). Hence, the interaction in the given: block will never get a chance to match.
Note
Mocking and stubbing of the same method call has to happen in the same interaction.


So the "correct" way to do it is like this:

Personally I don't think it reads that well and prefer the Mockito-style they say won't work. Interestingly this is the first time I've encountered something in Spock I didn't like, otherwise I think it's a very nice tool.
 
Tim Cooke
Sheriff
Posts: 4870
317
IntelliJ IDE Python Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Having read back over this discussion I realise that Junilu already posted this as a solution. I guess the two of us arriving at the same destination makes me feel a bit better than it's the right destination.
 
Junilu Lacar
Sheriff
Posts: 15754
264
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Independently arriving at the same solution seems a pretty good validation.
 
Asif Haciyev
Ranch Hand
Posts: 85
2
Netbeans IDE Oracle Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you both, Junilu and Tim. I am sorry, I couldn't reply you until now.
 
When all four tires fall off your canoe, how many tiny ads does it take to build a doghouse?
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
    Bookmark Topic Watch Topic
  • New Topic