2

一.后台单元测试中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


weiweiyi
1k 声望123 粉丝