如何在方法中测试业务逻辑?

时间:2018-01-28 19:45:52

标签: java testing mockito

我的服务层中有这样的方法:

public Long calculateItemsCostInShoppingCart(Long shoppingCartId) {
    List<Item> items = shoppingCartRepository.findAllItems(shoppingCartId);
    Long cost = 0L;
    for (Item item : items) {
        cost += item.getPrice();
    }
    return cost;
}

我需要测试列表中所有项目的汇总成本的计算。我被认为是mockito,但它没有成功,因为mockito只是创建存根,我需要真正的入口数据和基于它们的结果。怎么办?

5 个答案:

答案 0 :(得分:3)

//  create mock
ShoppingRepository mock = mock(ShoppingRepository.class);

// define return value for method findAllItems()
when(mock.findAllItems()).thenReturn(listOf(...));

答案 1 :(得分:1)

假设您正在开发在应用程序服务器上运行的Java Web应用程序,则另一个选项可能是使用Arquillian(http://arquillian.org/)。简而言之,Arquillian是一个框架,它允许您在将运行的环境中测试逻辑。但是将Arquillian集成到您的项目中可能需要做些工作。我们在几个项目中使用Arquillian,到目前为止效果很好。即使是Alpha版本的Persistence模块也能很好地工作。

答案 2 :(得分:1)

以下是如何使用Mockito进行测试的示例:

public class SomeCalculatorTest {

    @Mock
    private ShoppingCartRepository shoppingCartRepository;

    @InjectMocks
    private SomeCalculator someCalculator = new SomeCalculator();

    @Before
    public void setUp() {
        initMocks(this);
    }

    @Test
    public void testEmptyItemsList() {
        when(shoppingCartRepository.findAllItems(any())).thenReturn(new ArrayList<>());
        final Long result = someCalculator.calculateItemsCostInShoppingCart(1L);
        assertThat(result, is(0L));
    }

    @Test
    public void testOneItemInList() {
        when(shoppingCartRepository.findAllItems(any())).thenReturn(Arrays.asList(new ItemImpl(25L)));
        final Long result = someCalculator.calculateItemsCostInShoppingCart(1L);
        assertThat(result, is(25L));
    }

    @Test
    public void testTwoItemInList() {
        when(shoppingCartRepository.findAllItems(any())).thenReturn(Arrays.asList(new ItemImpl(25L), new ItemImpl(12L)));
        final Long result = someCalculator.calculateItemsCostInShoppingCart(1L);
        assertThat(result, is(37L));
    }
}

答案 3 :(得分:0)

  

我需要测试列表中所有项目的汇总成本的计算。

在这种情况下,您必须隔离不执行任何计算的shoppingCartRepository依赖项。

  

我需要真实的入口数据和基于它们的结果。怎么办?

它描述了集成测试。在这种情况下,请勿使用Mockito。

进行单元测试:

你必须模拟依赖关系,你还需要一种方法在被测试的类的实例中设置它 构造函数通常是一种很好的方法(让我们调用被测试的类MyService):

public MyService(ShoppingCartRepository shoppingCartRepository){
   this.shoppingCartRepository = shoppingCartRepository;
}

然后,在测试中你应该模拟ShoppingCartRepository,记录findAllItems()的行为并在MyService的构造函数中传递模拟。

@Mock
private ShoppingCartRepository shoppingCartRepositoryMock;

@Test
public void calculateItemsCostInShoppingCart(){

   Long cartId = Long.valueOf(123);   

   // set the dependency
   MyService myService = new MyService(shoppingCartRepositoryMock);

   // create the mock
   Mockito.when(shoppingCartRepositoryMock.findAllItems(cartId))
          .thenReturn(createMockedItems());

   //action
   Long actualCost = myService.calculateItemsCostInShoppingCart(cartId);

   // assertion
   Assert.assertEquals(expectedCost, actualCost);
}

 private List<Item> createMockedItems() { ... }

答案 4 :(得分:0)

您可以使用放心库进行测试 得到放心的响应对象,以及列表方法对象的调用方法。

@BeforeClass
public static void init() {
    RestAssured.baseURI = "http://localhost";
    RestAssured.port = 8080;
}
@Test
public void testUserRegistration() {
    Response response = 
            RestAssured
            .given()
            .get(URL_LOGIN)
            .then()
            .assertThat()
            .statusCode(200);

    Assert.assertThat(200, Matchers.is(200));
    Assert.assertThat(response.getStatusCode(), Matchers.is(200));
}