SpringBoot Test NullPointer Exception

39 views Asked by At

I am trying to test whether my SpringBoot Repository works adding the new User to database and I am getting a NullPointer Exception during the Junit test. Here is the code.

User:

package org.example;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.SpringBootConfiguration;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name="users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable=false, unique=true)
    private int creditCardNumber;

    @Column(nullable=false, unique=true)
    private String email;

    @Column(nullable=false)
    private String password;

}

UserRepository:

package org.example;

import org.example.User;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface UserRepository extends JpaRepository<User, Long>{

}

UserService:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Service;
@SpringBootApplication
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User createUser(Long id, int credit_card_number, String email, String password) {
        User user = new User(id,credit_card_number,email, password);
        return userRepository.save(user);
    }
}

and UserTest:

package org.example;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserTest {


    @Autowired
    private UserService userService;


    @Test
    public void testCreateUser() {
        User newUser = userService.createUser(Integer.toUnsignedLong(23), 203952, "[email protected]", "siofd");
        assertEquals(newUser.getEmail(), "[email protected]");
    }
}

My testing is throwing nullpointer exception during testCreateUser because I think in UserService, UserRepository is null.

I added the repository annotation to UserRepository. I tried adding the @SpringBootApplication. Could you maybe help why.

2

There are 2 answers

0
Feel free On
  1. You should not put @SpringBootApplication on your UserService class. This annotation should be on your main application class only.

  2. Use on top of your test class @ExtendWith(SpringExtension.class) for junit 5 and @RunWith(SpringRunner.class) for junit 4.

  3. For me your test should look like this:

    @ExtendWith(SpringExtension.class)
    @SpringBootTest
    public class UserServiceIntegrationTest {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    public void testCreateUser() {
        // given
        int creditCardNumber = 203952;
        String email = "[email protected]";
        String password = "siofd";
    
        User newUser = userService.createUser(null, creditCardNumber, email, password);
    
        User foundUser = userRepository.findById(newUser.getId()).orElse(null);
        assertThat(foundUser).isNotNull();
        assertThat(foundUser.getEmail()).isEqualTo(email);
        assertThat(foundUser.getPassword()).isEqualTo(password);
        assertThat(foundUser.getCreditCardNumber()).isEqualTo(creditCardNumber);
    }
    }
    
0
Tamas Csizmadia On

Fix UserService

First things first, please remove the @SpringBootApplication annotation from your UserService service.

Create a SpringBootApplication Annotated Class

Next, please create a class with a main method as entrypoint and annotate it with @SpringBootApplication. An example:

@SpringBootApplication
public class SpringSandboxApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSandboxApplication.class, args);
    }

}

Name SpringBootApplication class as you wish.

JUnit5 Sample Test

For the UserService a minimum working integration test with JUnit5:

@SpringBootTest
class UserServiceIT {

    @Autowired
    private UserService userService;

    @Autowired
    private UserRepository userRepository;

    @Test
    void testCreateUser() {
        User createdUser = userService.createUser(1L, 1234567890, "[email protected]", "password");
        User retrievedUser = userRepository.findById(1L).orElse(null);

        assertEquals(createdUser.getId(), retrievedUser.getId());
        assertEquals(createdUser.getCreditCardNumber(), retrievedUser.getCreditCardNumber());
        assertEquals(createdUser.getEmail(), retrievedUser.getEmail());
        assertEquals(createdUser.getPassword(), retrievedUser.getPassword());
    }
}

Depending on your pom.xml you may need to add Maven Failsafe Plugin definition to automatically run your integration tests invoking mvn:

<plugins>
    <build>
        <!-- your other plugin definitions -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.1.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Results of mvn verify:

2024-01-05T12:05:12.752+01:00  INFO 56206 --- [           main] c.g.t.s.service.UserServiceIT            : Started UserServiceIT in 1.462 seconds (process running for 1.894)
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.015 s -- in com.github.tcsizmadia.springsandbox.service.UserServiceIT
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] 
[INFO] --- failsafe:3.1.2:verify (default) @ spring-sandbox ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.708 s
[INFO] Finished at: 2024-01-05T12:05:13+01:00
[INFO] ------------------------------------------------------------------------