3

记录本周遇到的问题

 2 years ago
source link: https://segmentfault.com/a/1190000041437653
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK