mockito 简单JUnit测试失败

k2fxgqgv  于 2022-11-08  发布在  其他
关注(0)|答案(2)|浏览(273)

我想学习如何编写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);
    }

问题是这个简单的Assert已经失败了。返回的列表是空的。我知道,我对这一切都是新手,但从我的Angular 来看,失败是如此的意外,以至于我没有办法解决这个问题。
这是整个代码(不多):

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()创建一个工作测试?谢谢你的帮助!

utugiqy6

utugiqy61#

以下是我的建议:您应该重构代码并应用构造函数注入样式,如下所示:

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变得非常简单,测试起来也很容易。

apeeds0o

apeeds0o2#

初始化模拟两次-第一次使用@RunWith(MockitoJUnitRunner.class),然后使用MockitoAnnotations.openMocks(this);
这意味着,当您输入setUp方法时:

  • customerRepository指向R1
  • customerService。customerRepository指向R1

而在这个方法之后

  • customerRepository指向R2
  • customerService。customerRepository指向R1

这意味着您的服务未重新初始化
使用调试器确认此观察结果。
@InjectMocks javadoc说:
必须调用openMocks(this)方法来初始化带注解的对象。在上面的例子中,openMocks()是在测试的基类的@Before(JUnit 4)方法中调用的。对于JUnit 3,openMocks()可以转到基类的setup()方法。**相反,**您也可以将openMocks()放在您的JUnit运行程序(@RunWith)中,或者使用内置的MockitoJUnitRunner。

相关问题