記錄本周遇到的問題

weiewiyi發表於2022-02-22

一.後臺單元測試中run,和debug模式測試結果不同

image.png

目前測試controller控制器下update方法的流程圖
image.png

目前問題出在引數捕獲上。在debug模式下,當我用一行行執行下去的時候,執行到下面第二行entityArgumentCaptor.getValue()的時候測試報錯說並沒有捕獲到資料

1 Mockito.verify(this.Service).update(longArgumentCaptor.capture(),
        entityArgumentCaptor.capture());
2 Assertions.assertEquals(oldEntity.getName(), entityArgumentCaptor.getValue().getName());

來看看報錯
image.png

它說引數沒有捕獲,可能是因為兩個原因
1.可能沒有verify()中使用argument.captrue()
2.可能在某個樁中使用的capture(),但是沒有被呼叫。並推薦只在 verify()中使用capture()。

最後還貼心地給出例子:
image.png

但是和上述程式碼一比較就發現用法完全和推薦的一致

然後又試著直接用run模式測試,結果竟然通過了。
image.png

最後測試了很久,報錯原因是我沒有把verify()裡的兩個引數寫在同一行,如圖204行和205行
image.png

在我沒有把引數寫在同一行的時候,debug模式下,點下一步,跳到204行,接著跳到205行,然後不知為何又跳回204行。而204行只有id的引數捕獲。

經過測試,兩個捕獲器都沒有捕獲到引數。

猜測可能是因為debug是一行一行地執行語句,當不把引數寫在同一行時,執行就可能出錯,語句直接失敗。

之後把引數放在同一行之後,debug模式下執行結果正確。

二.jpa引數不允許為null

情景:查詢引數name 為空時顯示所有資料,前臺向後臺傳了查詢條件name為null
image.png
在測試的時候發現報錯
image.png

jpa定義的查詢

Page<PropertyCompany> findAllByNameContainingAndDeletedIsFalse(String name, Pageable pageable);

原因:jpa的findByXXX 引數不允許為null。

解決辦法:
1:service層加判斷,為null時設定為空字串。

public Page<PropertyCompany> page(String name, @NotNull Pageable pageable) {
    if (name == null) {
      name = "";
    }

2.自定義查詢:

default Page<PropertyCompany> findAll(String name, @NotNull Pageable pageable) {
        Specification<PropertyCompany> specification = PropertyCompanySpecs.containingName(name);
        return this.findAll(specification, pageable);
    }

public class PropertyCompanySpecs {
    public static Specification<PropertyCompany> containingName(String name) {
        if (name != null && !name.trim().isEmpty()) {
            return (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.like(root.get("name").as(String.class), String.format("%%%s%%", name.trim()));
        } else {
            return Specification.where(null);
        }
    }
}

如果確實想要查詢name為null的欄位怎麼辦?

可以使用:findByNameIsNull 相當於sql語句 where name is null

三 傳值問題

背景為angular中父元件呼叫子元件,並讓子元件操作傳入的陣列。

父元件: 定義了villages: Village[];
並在v層中傳給了子元件

<component [setVillages]="villages"></component>`

子元件:為了避免在使用villages.push等操作的時候,因為傳入的villages是undefined而導致報錯,做了以下操作:

if (village === undefined) {
  villages = new Array<Village>();
}

結果:子元件最後對villages的操作影響不到父元件的villages,父元件中的villages還是undefined。

解決辦法: 父元件中定義villages初始變數應該這麼定義:
villages = new Array<Village>();

目前認為是:跟c語言類似,如果函式的引數不傳入引數地址,代表著操作的只是一份資料的拷貝。而如果傳入引數的地址,代表著操作的是真正傳入資料,函式外的那個變數也會隨之改變。
在這裡,陣列如果在子元件new Array(),代表記憶體在子元件這裡開闢,對資料的操作並不影響父元件的資料.而如果陣列在父元件這裡開闢空間,就代表子元件操作的是父元件的資料。
image.png

相關文章