简单的JUnit测试失败。

3
我希望学习如何编写JUnit测试,但我失败了。
这是我的测试:
    @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);
    }

问题在于这个简单的断言已经失败了。返回的列表是空的。 我知道,我对这一切都很陌生,但是从我的角度来看,这个失败是如此出乎意料,以至于我不知道如何解决这个问题。
这是整个代码(并不多):
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);
    }
}

需要测试的函数就是这个,我知道它是有效的:

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

实际上,我只是想学习如何编写此类测试,但几天来一直未能编写出一个。虽然有很多示例和解释,但无论我尝试什么,都没有成功的测试。

如何为getAllCustomers()创建一个可行的测试?感谢您的帮助!

2个回答

1
这是我的建议:您应该重构代码并应用构造函数注入的方式,就像这样:
public class CustomerService {

  private final CustomerRepository customerRepository;

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

  // ...

}

那么,您就不需要任何Mockito注释。只需将它们移除即可。
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
    }

}


你可以看到,CustomerServiceTests变得非常简单和琐碎易测。

0
您将模拟对象初始化了两次 - 首先是通过@RunWith(MockitoJUnitRunner.class),然后是使用MockitoAnnotations.openMocks(this); 这意味着当您进入setUp方法时:
  • customerRepository指向R1
  • customerService.customerRepository指向R1
而在此方法之后:
  • customerRepository指向R2
  • customerService.customerRepository指向R1
这意味着您的服务未被重新初始化
请使用调试器确认此观察结果。
@InjectMocks javadoc说:

必须调用MockitoAnnotations.openMocks(this)方法来初始化带注释的对象。在上面的示例中,openMocks()在测试的基类的@Before(JUnit4)方法中调用。对于JUnit3 openMocks(),可以转到基类的setup()方法中。或者您也可以将openMocks()放在您的JUnit运行器(@RunWith)中或使用内置的MockitoJUnitRunner。


1
非常感谢!您的解释真的帮助我更好地理解机制。我总是尝试查看文档,但当然,由于信息量很大,如果您对所有这些都是新手,那么跟踪就不那么容易了。 - FrozenTree

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接