Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple JUnit test fails

I want to learn how to write JUnit tests and I fail completely.

This is my test:

    @Test
    public void testGetAllCustomers() {
        // given
        List<Customer> customerList = new ArrayList<Customer>();
        customerList.add(c1);
        customerList.add(c2);
        customerList.add(c3);
        given(customerRepository.findAll()).willReturn(customerList);
            
        // when
        List<Customer> resultList = customerService.getAllCustomers();
        
        // then
        assertThat(resultList).hasSize(3);
    }

The problem is that this simple assertion already fails. The returned list is empty. I know, I am new to all of this, but the failure is so unexpected from my point of view that I have no approach on how to solve the problem.

This is the whole code (not that much):

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class CustomerServiceTests {
    
    @Mock
    private CustomerRepository customerRepository;
    
    @InjectMocks
    private CustomerService customerService;
    
    private Customer c1 = new Customer(
            1L, 
            "Hans Meyer", 
            false, 
            Timestamp.from(Instant.now()),
            null,
            null
    );
    private Customer c2 = new Customer(
            2L, 
            "Marie Hollande", 
            true, 
            Timestamp.from(Instant.now()),
            null,
            null
    );
    private Customer c3 = new Customer(
            3L, 
            "Mohammed Abbas", 
            false, 
            Timestamp.from(Instant.now()),
            null,
            null
    );
    
    @Before
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void testGetAllCustomers() {
        // given
        List<Customer> customerList = new ArrayList<Customer>();
        customerList.add(c1);
        customerList.add(c2);
        customerList.add(c3);
        given(customerRepository.findAll()).willReturn(customerList);
        
        // when
        List<Customer> resultList = customerService.getAllCustomers();
        
        // then
        assertThat(resultList).hasSize(3);
    }
}

The function to test is just this and I know that it works:

public List<Customer> getAllCustomers() {
        return customerRepository.findAll();
}

Actually, I just want to learn how to write such tests, but for days I have been failing to write one. There are quite a few examples and explanations, but no matter what I try, I have not yet managed a working test. How to create a working test for getAllCustomers()? Thank you for your help!

like image 459
FrozenTree Avatar asked Apr 15 '26 09:04

FrozenTree


1 Answers

Here's my recommendation: you should refactor your code and apply constructor-injection style, like this:

public class CustomerService {

  private final CustomerRepository customerRepository;

  public CustomerService(CustomerRepository customerRepository) {
    this.customerRepository = customerRepository;       // inject customerRepository via constructor
  }

  // ...

}

then, you don't need any Mockito annotations. Just remove them.

public class CustomerServiceTests {

    private CustomerRepository customerRepository; 
    private CustomerService customerService;

    // ... init Customer

    @Before
    public void setup() {
      customerRepository = mock(CustomerRepository.class); // inject mocked customerRepository via constructor
      customerService = new CustomerService(customerRepository);
    }

    @Test
    public void testGetAllCustomers() {
        // same as your test code
    }

}

You can see that CustomerServiceTests becomes very simple and trivial to test.

like image 151
Kai-Sheng Yang Avatar answered Apr 17 '26 23:04

Kai-Sheng Yang