[英]Testing a method which calls another method
I have a method in my service layer:我的服务层中有一个方法:
public List<String> sortBarcodesByTotalPrice(Set<String> barcodesByBookType) {
List<String> toSort = new ArrayList<>();
for (String barcode : barcodesByBookType) {
[1] String combined = barcode + "/" + priceOperations.calculatePriceByBarcode(barcode);
toSort.add(combined);
}
[2] toSort.sort(new TotalPriceComparator());
return toSort;
}
[1] this line gets barcode, lets say "ABC"
and then calls a method in another class which retrieves information from the database about that item, performs calculation and returns the price. [1] 此行获取条形码,假设为
"ABC"
,然后调用另一个 class 中的方法,该方法从数据库中检索有关该项目的信息,执行计算并返回价格。 The possible combined
value could be something like "ABC/10"
.可能的
combined
值可能类似于"ABC/10"
。
[2] sorts all the values by price, ascending. [2] 按价格升序对所有值进行排序。 So if List contains and
"DEF/15"
and "ABC/10"
it gets sorted to [0] = "ABC/10"
, [1]= "DEF/15"
.因此,如果 List 包含
"DEF/15"
和"ABC/10"
,它将被排序为[0] = "ABC/10"
, [1]= "DEF/15"
。
When I try to test this method, I get null pointer exception when priceOperations.calculatePRiceByBarcode(barode)
gets called.当我尝试测试此方法时,
priceOperations.calculatePRiceByBarcode(barode)
时出现 null 指针异常。 How do I test this method?我如何测试这种方法? I've tried searching and found some questions and answers about using mockito but I can't figure out how to implement this.
我尝试搜索并找到了一些关于使用 mockito 的问题和答案,但我不知道如何实现这一点。
my current attempt at testing this method:我目前测试此方法的尝试:
@Test
void sortBarcodesByTotalPrice() {
Set<String> toSort = new HashSet<>();
toSort.add("ABC/10");
toSort.add("DEF/5");
toSort.add("GHI/15");
List<String> sorted = bookService.sortBarcodesByTotalPrice(toSort);
assertEquals(sorted.get(0), "GHI");
assertEquals(sorted.get(1), "ABC");
assertEquals(sorted.get(2), "DEF");
}
EDIT, SOLUTION: I have figured out how to solve this thanks to information from Kaj Hejer .编辑,解决方案:感谢Kaj Hejer提供的信息,我已经想出了如何解决这个问题。 This is my new test method, passing and working as intended, if I understand this correctly:
这是我的新测试方法,如果我理解正确的话,可以按预期通过和工作:
@Test
void sortBarcodesByTotalPrice() {
PriceOperations priceOperations = Mockito.mock(PriceOperations.class);
Set<String> toSort = new HashSet<>();
toSort.add("GHI");
toSort.add("ABC");
toSort.add("DEF");
when(priceOperations.calculatePriceByBarcode("GHI")).thenReturn(new BigDecimal("15"));
when(priceOperations.calculatePriceByBarcode("ABC")).thenReturn(new BigDecimal("10"));
when(priceOperations.calculatePriceByBarcode("DEF")).thenReturn(new BigDecimal("5"));
BookService bookService = new BookService(null, null, priceOperations);
List<String> sorted = bookService.sortBarcodesByTotalPrice(toSort);
assertEquals(sorted.get(0), "DEF/5");
assertEquals(sorted.get(1), "ABC/10");
assertEquals(sorted.get(2), "GHI/15");
}
First you have to decide what to test where.首先,您必须决定在哪里测试什么。 You might want to have separate tests for BookService and for the PriceOperations class.
您可能希望对 BookService 和 PriceOperations class 进行单独的测试。 Now your test are tesing both these classes.
现在您的测试正在测试这两个类。
If you want to write a test for the BookService class you can mock the PriceOperations class.如果您想为 BookService class 编写测试,您可以模拟 PriceOperations class。
List<String> sorted = new ArrayList<>();
sorted.add("GHI");
sorted.add("ABC");
sorted.add("DEF");
PriceOperations priceOperations = Mockito.mock(PriceOperations.class);
when(priceOperations. calculatePriceByBarcode(Mockito.<String>anyList())).thenReturn(sorted);
When injecting the PriceOperations into the BookService constructor injection is a smart way of injecting because it make it easier to write tests.将 PriceOperations 注入 BookService 构造函数时,注入是一种聪明的注入方式,因为它使编写测试更容易。 Then you can inject the mocked priceOperations with
然后你可以注入模拟的 priceOperations
BookService bookService = new BookService(priceOperations);
Please let me know if this is useful!请让我知道这是否有用!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.