Win a copy of The Journey To Enterprise Agility this week in the Agile and Other Processes forum! And see the welcome thread for 20% off.
  • 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:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Campbell Ritchie
  • Tim Cooke
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Junilu Lacar
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Ganesh Patekar
  • Tim Moores
  • Pete Letkeman
  • Stephan van Hulst
Bartenders:
  • Carey Brown
  • Tim Holloway
  • Joe Ess

What are some of the usual causes of tests which return null?  RSS feed

 
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm working on a Spring Boot 2 project which is programmed using Kotlin and WebFlux/Projectreactor.io
Currently I'm trying to figure out why when I call a mocked method I get NPE, but when I call the method normally things work.

What are some common causes of a test null, but when you call the method outside of the test environment the code works?
 
Marshal
Posts: 4454
284
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Usually with mock frameworks you get a null back from a method call on a mocked object, unless you've configured it otherwise. Perhaps you're calling a method on a mock object, they trying to do something with the object returned?
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think I'm doing that, but I could be wrong.
Here is a link to the GitHub https://github.com/letkemanpete78/exercise-listing, but the code in question is listed below:
Unit test:Here is the code that the unit test is trying to execute and return a NPE
ExerciseService:
 
Rancher
Posts: 3595
39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, I don't know Kotlin, but hopefully I can interpret that code well enough.

Your mocking for save(ex1) uses an Exercise object that looks like it has an id of "1"?

The actual call to save appears to be using an Exercise object with a random UUID (called exerciseID).
I can't see how it can match, unless equals ignores the id.
This assumes that Exercise has some form of equals method in the first place.

ETA:  Indeed, the filename is essentially random (as far as the test is concerned) as well, as it uses the current time, whereas your ex1 in the test has "fileName 1.png".
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:Your mocking for save(ex1) uses an Exercise object that looks like it has an id of "1"?

Correct

Dave Tolls wrote:The actual call to save appears to be using an Exercise object with a random UUID (called exerciseID).
I can't see how it can match, unless equals ignores the id.
This assumes that Exercise has some form of equals method in the first place.


However shouldn't this return with an object that has an id value of 1 along with the other constant values?

Exercise, is a Kotlin data class which does indeed have an equals method.
 
Dave Tolls
Rancher
Posts: 3595
39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your given is saying that when save is called with a value equal to ex1 then return whatever that Mono thing is doing.

The code then calls save, but with an Exercise that has an id of <some random UUID> and a filename of <some timestamp>.
That will not equal the given ex1 values.
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that I'm missing something here.
What if we remove the Mono from the example then we get something like When you explicitly create a value for a mock method as shown are you not telling the framework that when you call that you will get in return?

The ExerciseService calls the myClass.save(item) and the returned value in this instance is a null value for some reason, and the mocked return value is not a null.
 
Dave Tolls
Rancher
Posts: 3595
39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What you are telling Mockito with:

is that when save is called with an item that is equal to the given item, then do the return bit.

So Mockito will only react to a call to save that matches the given item.

In your case, the "item" you have told it to match is an Exercise object ex1, which has the values:
"1", "Name #1", "Description #1", "fileName 1.png", true

However your call to save has an Exercise object with the values:
<Some random UUID>, "Name #1", "Description #1",<Some date stamped file name>, true

Those two things are not the same, so Mockito doesn't match them, so falls back to the default return of null.

Now, the question is, do you need to match the actual values (is that part of the test), or is it sufficient to tell Mockito to return the required value whenever save is called with any Exercise object.

If it's the latter then you could use the any(Exercise.class) matcher (check the syntax with the docs).
If it's the former then you may need to write your own as you'll need to only match on certain attributes of Exercise.
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interesting this code/test seems to work: However it does not use the given().willReturn() method(s) attached to the repository.save() method. Plus I replaced the MockBean notation with Autowired.
I suspect that somehow the value of repository.save(ex1) call is being cached and being used/returned when the exerciseService.createExercise(Flux.just(file1), ex1) method is executed.

What Dave previously does make a lot of sense to me about using any(Exercise.class). But when I tried that I still ended up with a NPE.
I suspect that this has to do with repository.save(ex1) not allowing nulls and any(Exercise.class) could be filling the arguments with null values.

One thing is very clear, I still have much to learn with regards to everything that I'm using.
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually this line is not needed at all
 
Dave Tolls
Rancher
Posts: 3595
39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, that version isn't mocking the repository at all, so I assume the ExerciseRepository is doing its proper work.

The other given() calls are either to a method that has no parameters, so will always match, or has been supplied an any() Matcher, so will also always match.

any(Exercise.class) should work, but not seeing the code that apparently didn't work I can't say what happened there.
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dave Tolls wrote:any(Exercise.class) should work, but not seeing the code that apparently didn't work I can't say what happened there.


Translates into:
Which generates the following error message:
ReactiveCrudRepository is a Spring 5/Spring Boot 2 interface.

This Spring 5/Spring Boot 2 and Kotlin are both fairly new as such I suspect that there is something more that need to be done to get this to work.

I'm going to move on with the project and come back to this test and other test which require the use of the repository.save method later on.
Maybe I'll do the testing of these method using Java instead of Kotlin, but that won't be for at least a few days or more.
 
Pete Letkeman
Saloon Keeper
Posts: 1797
74
Android Chrome IntelliJ IDE Java MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To finish this up:

I did end up creating the tests in Java only to find out that I the other programming I did had some issues.
The other programming appeared to be working, but a few assumptions where being made.

Once I fixed the other programming I was able to finish creating my unit tests in Java.
After which I took the tests where were programming in Java and migrated them to Kotlin.

Looks like writing these tests may have saved me from some possible problems in the future.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!