A common reason for Null Pointer Exceptions in Java is a variable redeclaration instead of instantiation. Learn what that means, how to avoid it, and how to spot it, in this presentation.
Read the full blog post: http://testerhq.com/post/blogs/javafortesters/2017-08-29-faq-null-pointer-exception/
Visit my Java Web Site: http://javafortesters.com
---
# FAQ - why does my code throw a null pointer exception - common reason #1 Redeclaration
- Using `@BeforeClass` or `@Before` can setup data for use in tests
- Any 'variables' we instantiate need to be 'fields' rather than variables
- We want to instantiate them in the setup method rather than redeclare them
---
# Example of the Problem
I know I will use an `Adder` in my test so I create it as a field:
~~~~~~~~
public class WhyCodeThrowsNullPointerExceptionTest {
Adder adder;
~~~~~~~~
I don't want to re-instantiate it each time so I make an `@BeforeClass` method to instantiate it:
~~~~~~~~
@BeforeClass
public static void setupAdder(){
Adder adder = new Adder();
}
~~~~~~~~
**Warning: Error in the above code**
---
# Semantic Error
I just made a Semantic coding error. This won't be caught by a compiler, but it will cause my `@Test` to fail with a Null Pointer Exception.
In the setup method I really wanted to assign a value to the field, instead I created an new variable with the same name.
# In General
- Try to write one test at a time so that if you have a problem it is easier to identify where the problem is
- Try to write working isolated tests and then refactor to a more general solution when you need it - that way, you know it was working, so you just have to work backwards to find out what went wrong
- Try to use automated IDE refactoring rather than move code around manually
- Use the IDE syntax highlighting to help spot any issues
3. FAQ ‐ why does my code throw a null
pointer exception ‐ common reason #1
Redeclaration
Using @BeforeClass or @Before can setup data for use in tests
Any 'variables' we instantiate need to be 'fields' rather than
variables
We want to instantiate them in the setup method rather than
redeclare them
@eviltester 3
4. Example of the Problem
I know I will use an Adder in my test so I create it as a field:
public class WhyCodeThrowsNullPointerExceptionTest {
Adder adder;
I don't want to re‐instantiate it each time so I make an
@BeforeClass method to instantiate it:
@BeforeClass
public static void setupAdder(){
Adder adder = new Adder();
}
Warning: Error in the above code
@eviltester 4
5. Semantic Error
I just made a Semantic coding error. This won't be caught by a
compiler, but it will cause my @Test to fail with a Null Pointer
Exception.
@Test
public void canAddTwoPlusTwo(){
Assert.assertEquals(4,adder.add(2,2));
}
The above test will fail with a NullPointerException
java.lang.NullPointerException
at com.javafortesters.faq.nullpointerexception.
WhyCodeThrowsNullPointerExceptionTest.canAddTwoPlusTwo
(WhyCodeThrowsNullPointerExceptionTest.java:29)
...
@eviltester 5
6. What Went Wrong?
In the setup method I really wanted to assign a value to the field,
instead I created an new variable with the same name.
Adder adder = new Adder();
I really wanted:
adder = new Adder();
and to support that, the field really needs to be declared as static
static Adder adder;
@eviltester 6
7. How to avoid? IDE Syntax Highlighting
If I was editing this in an IDE, then I would see that the adder in
the following line is never used :
Adder adder = new Adder();
It will be coloured grey or some other IDE indication.
@eviltester 7
8. static methods need static fields
In order for the field to be used in the static method it needed to
be static.
If I had used it in the setup method:
Adder adder;
@BeforeClass
public static void setupAdder(){
adder = new Adder();
}
Then I would have seen a syntax error in the code because:
Non‐static field 'adder' cannot be referenced from a
static context
@eviltester 8
10. Refactor to fields
Had I written the @Test code first then I would have started with:
@Test
public void canAddTwoPlusTwo(){
Adder adder = new Adder();
Assert.assertEquals(4,adder.add(2,2));
}
I can refactor this to avoid errors.
@eviltester 10
11. Automated refactoring of Extract to field
where initialized as 'field declaration
Might have generated the following code:
private final Adder adder = new Adder();
this removes the need for an @BeforeClass or @Before
construct entirely
@eviltester 11
12. Automated refactoring of Extract to field
where initialized in constructor
private final Adder adder;
public WhyCodeThrowsNullPointerExceptionTest() {
adder = new Adder();
}
this removes the need for an @BeforeClass or @Before
construct entirely
@eviltester 12
13. Automatically Refactor prior to using
@Before...
I might still want to use an @BeforeClass or @Before
To make the code readable
I could do that
but I don't think I would have declared a new variable after the
refactorings because I have a working code example that I'm
moving.
@eviltester 13
14. In General
Try to write one test at a time so that if you have a problem it is
easier to identify where the problem is
Try to write working isolated tests and then refactor to a more
general solution when you need it ‐ that way, you know it was
working, so you just have to work backwards to find out what
went wrong
Try to use automated IDE refactoring rather than move code
around manually
Use the IDE syntax highlighting to help spot any issues
@eviltester 14
15. Source Code
If you want to experiment with code that recreates this
problem then have a look at
WhyCodeThrowsNullPointerExceptionTest.java in
javaScratchpad
@eviltester 15
16. "Java For Testers" A Book for
learning how to code Java
All code written as Test methods
you learn TDD
your learn JUnit
you focus on code
you are not distracted by 'creating an application'
Affordably priced so that everyone can learn ﴾Free Download of
70+ Sample PDF﴿
@eviltester 16
17. BIO ‐ Alan Richardson
Alan Richardson has more than twenty years of professional IT
experience, working as a programmer and at every level of the
testing hierarchy from tester through head of testing. He has
performed keynote speeches and tutorials at conferences
worldwide. Author of multiple books on testing and automating.
Alan also has created online training courses to help people learn
Technical Web Testing and Selenium WebDriver with Java. He works
as an independent consultant, helping companies improve their use
of automation, agile, and exploratory technical testing.
@eviltester 17
20. Books Written By Alan Richardson
Java For Testers
Dear Evil Tester
Automating and Testing a REST API
Selenium Simplified
@eviltester 20
21. Online Training Courses By Alan
Richardson
Selenium Webdriver With Java
Technical Web Testing 101
Evil Tester Talks: Technical Testing
Case Study: Java Desktop Application Technical Training
@eviltester 21