资讯专栏INFORMATION COLUMN

对象克隆问题

JeOam / 1783人阅读

摘要:断言不确定度,非强检器具,参量以及附加参量都修改成功。再次执行测试,出现了预期中的错误,证明就是对象引用的问题。

问题描述

编写观察者的单元测试,执行以下测试通过。断言不确定度,非强检器具,参量以及附加参量都修改成功。

@Test
public void updateTest() {

    logger.debug("0. 基础信息准备");

    logger.debug("构造计量单位");
    MeasurementUnit oldMeasurementUnit = measurementUnitService.getOneSavedMeasurementUnit();

    logger.debug("1. 初始化不确定度实体");

    logger.debug("获取基础的不确定度");
    AccuracyUncertainty accuracyUncertainty1 = accuracyUncertaintyService.getOneUnSavedObject();
    AccuracyUncertainty accuracyUncertainty2 = accuracyUncertaintyService.getOneUnSavedObject();
    AccuracyUncertainty accuracyUncertainty3 = accuracyUncertaintyService.getOneUnSavedObject();
    accuracyUncertaintyService.getOneSavedObject();

    logger.debug("设置不确定度1的最小与最大单位");
    accuracyUncertainty1.setMinAccuracyUnit(oldMeasurementUnit);
    accuracyUncertainty1.setMaxAccuracyUnit(oldMeasurementUnit);

    logger.debug("设置不确定度2的最小单位");
    accuracyUncertainty2.setMinAccuracyUnit(oldMeasurementUnit);

    logger.debug("设置不确定度3的最大单位");
    accuracyUncertainty3.setMaxAccuracyUnit(oldMeasurementUnit);

    logger.debug("持久化不确定度列表");
    List accuracyUncertaintyList = new ArrayList<>();
    accuracyUncertaintyList.add(accuracyUncertainty1);
    accuracyUncertaintyList.add(accuracyUncertainty2);
    accuracyUncertaintyList.add(accuracyUncertainty3);
    accuracyUncertaintyRepository.save(accuracyUncertaintyList);

    logger.debug("2. 初始化内嵌不确定度");
    AccuracyEmbeddable accuracyEmbeddable1 = this.getOneAccuracyEmbeddable();
    AccuracyEmbeddable accuracyEmbeddable2 = this.getOneAccuracyEmbeddable();
    AccuracyEmbeddable accuracyEmbeddable3 = this.getOneAccuracyEmbeddable();

    logger.debug("设置内嵌不确定度1的最大与最小单位");
    accuracyEmbeddable1.setMinAccuracyUnit(oldMeasurementUnit);
    accuracyEmbeddable1.setMaxAccuracyUnit(oldMeasurementUnit);

    logger.debug("设置内嵌不确定度2的最小单位");
    accuracyEmbeddable2.setMinAccuracyUnit(oldMeasurementUnit);

    logger.debug("设置内嵌不确定度3的最大单位");
    accuracyEmbeddable3.setMaxAccuracyUnit(oldMeasurementUnit);

    logger.debug("3. 初始化内嵌测量范围");
    MeasureScaleEmbeddable measureScaleEmbeddable1 = this.getOneMeasureScaleEmbeddable();
    MeasureScaleEmbeddable measureScaleEmbeddable2 = this.getOneMeasureScaleEmbeddable();
    MeasureScaleEmbeddable measureScaleEmbeddable3 = this.getOneMeasureScaleEmbeddable();

    logger.debug("设置内嵌测量范围1的最大与最小单位");
    measureScaleEmbeddable1.setMinMeasureScaleUnit(oldMeasurementUnit);
    measureScaleEmbeddable1.setMaxMeasureScaleUnit(oldMeasurementUnit);

    logger.debug("设置内嵌测量范围2的最小单位");
    measureScaleEmbeddable2.setMinMeasureScaleUnit(oldMeasurementUnit);

    logger.debug("设置内嵌测量范围3的最大单位");
    measureScaleEmbeddable3.setMaxMeasureScaleUnit(oldMeasurementUnit);

    logger.debug("4. 初始化非强检器具");
    NonMandatoryInstrument nonMandatoryInstrument1 = nonMandatoryInstrumentService.getOneUnSavedObject();
    NonMandatoryInstrument nonMandatoryInstrument2 = nonMandatoryInstrumentService.getOneUnSavedObject();
    NonMandatoryInstrument nonMandatoryInstrument3 = nonMandatoryInstrumentService.getOneUnSavedObject();
    nonMandatoryInstrumentService.getOneSavedObject();

    nonMandatoryInstrument1.setMeasureScale(measureScaleEmbeddable1);
    nonMandatoryInstrument2.setMeasureScale(measureScaleEmbeddable2);
    nonMandatoryInstrument3.setMeasureScale(measureScaleEmbeddable3);

    List nonMandatoryInstrumentList = new ArrayList<>();
    nonMandatoryInstrumentList.add(nonMandatoryInstrument1);
    nonMandatoryInstrumentList.add(nonMandatoryInstrument2);
    nonMandatoryInstrumentList.add(nonMandatoryInstrument3);

    nonMandatoryInstrumentRepository.save(nonMandatoryInstrumentList);

    logger.debug("5. 初始化参量");
    Parameter parameter1 = parameterService.getOneUnsavedObject();
    Parameter parameter2 = parameterService.getOneUnsavedObject();
    Parameter parameter3 = parameterService.getOneUnsavedObject();
    Parameter parameter4 = parameterService.getOneUnsavedObject();
    Parameter parameter5 = parameterService.getOneUnsavedObject();
    Parameter parameter6 = parameterService.getOneUnsavedObject();
    parameterService.getOneSavedObject();

    parameter1.setAccuracy(accuracyEmbeddable1);
    parameter2.setAccuracy(accuracyEmbeddable2);
    parameter3.setAccuracy(accuracyEmbeddable3);
    parameter4.setMeasureScale(measureScaleEmbeddable1);
    parameter5.setMeasureScale(measureScaleEmbeddable2);
    parameter6.setMeasureScale(measureScaleEmbeddable3);

    List parameterList = new ArrayList<>();
    parameterList.add(parameter1);
    parameterList.add(parameter2);
    parameterList.add(parameter3);
    parameterList.add(parameter4);
    parameterList.add(parameter5);
    parameterList.add(parameter6);

    parameterRepository.save(parameterList);

    logger.debug("6. 初始化附加参量");
    AdditionalParameter additionalParameter1 = additionalParameterService.getOneUnsavedObject();
    AdditionalParameter additionalParameter2 = additionalParameterService.getOneUnsavedObject();
    AdditionalParameter additionalParameter3 = additionalParameterService.getOneUnsavedObject();
    additionalParameterService.getOneSavedObject();

    additionalParameter1.setMeasureScale(measureScaleEmbeddable1);
    additionalParameter2.setMeasureScale(measureScaleEmbeddable2);
    additionalParameter3.setMeasureScale(measureScaleEmbeddable3);

    List additionalParameterList = new ArrayList<>();
    additionalParameterList.add(additionalParameter1);
    additionalParameterList.add(additionalParameter2);
    additionalParameterList.add(additionalParameter3);

    additionalParameterRepository.save(additionalParameterList);

    logger.debug("7. 初始化检定能力");

    logger.debug("8. 初始化参量检定能力");

    logger.debug("9. 初始化附加参量检定能力");

    logger.debug("10. 初始化校准能力");

    logger.debug("11. 初始化参量校准能力");

    logger.debug("12. 初始化附加参量校准能力");

    logger.debug("13. 构造新计量单位");
    MeasurementUnit newMeasurementUnit = new MeasurementUnit();
    String name = CommonService.getRandomStringByLength(10);
    newMeasurementUnit.setName(name);
    newMeasurementUnit.setSymbol("km");
    newMeasurementUnit.setMultiple((oldMeasurementUnit.getMultiple() + 10) * 2);
    newMeasurementUnit.setMeasurementUnitCategory(measurementUnitCategoryService.getOneSavedMeasurementUnitCategory());

    logger.debug("14. 更新并断言");
    Long id = oldMeasurementUnit.getId();
    measurementUnitService.update(id, newMeasurementUnit);
    MeasurementUnit updatedMeasurementUnit = measurementUnitRepository.findOne(id);
    assertThat(updatedMeasurementUnit.getName()).isEqualTo(newMeasurementUnit.getName());
    assertThat(updatedMeasurementUnit.getSymbol()).isEqualTo(newMeasurementUnit.getSymbol());
    assertThat(updatedMeasurementUnit.getMultiple()).isEqualTo(newMeasurementUnit.getMultiple());
    assertThat(updatedMeasurementUnit.getMeasurementUnitCategory()).isEqualTo(newMeasurementUnit.getMeasurementUnitCategory());

    logger.debug("15. 断言相关不确定度");
    List accuracyUncertainties = accuracyUncertaintyRepository.findAllByMinAccuracyUnit_IdOrMaxAccuracyUnit_Id(id, id);
    Assertions.assertThat(accuracyUncertainties.size()).isEqualTo(3);

    for (AccuracyUncertainty accuracyUncertainty : accuracyUncertainties) {
        if (accuracyUncertainty.getMinAccuracyUnit().getId().equals(id)) {
            Assertions.assertThat(accuracyUncertainty.getMinAccuracyAbsoluteValueInTest()).isEqualTo(accuracyUncertainty.getMinAccuracyValue() * newMeasurementUnit.getMultiple());
        }
        if (accuracyUncertainty.getMaxAccuracyUnit().getId().equals(id)) {
            Assertions.assertThat(accuracyUncertainty.getMaxAccuracyAbsoluteValueInTest()).isEqualTo(accuracyUncertainty.getMaxAccuracyValue() * newMeasurementUnit.getMultiple());
        }
    }

    logger.debug("16. 断言相关非强检器具");
    List nonMandatoryInstruments = nonMandatoryInstrumentRepository.findAllByMeasureScale_MinMeasureScaleUnit_IdOrMeasureScale_MaxMeasureScaleUnit_Id(id, id);
    Assertions.assertThat(nonMandatoryInstruments.size()).isEqualTo(3);

    for (NonMandatoryInstrument nonMandatoryInstrument : nonMandatoryInstruments) {
        MeasureScaleEmbeddable measureScaleEmbeddable = nonMandatoryInstrument.getMeasureScale();
        if (measureScaleEmbeddable.getMinMeasureScaleUnit().getId().equals(id)) {
            Assertions.assertThat(measureScaleEmbeddable.getMinMeasureScaleAbsoluteValueInTest()).isEqualTo(measureScaleEmbeddable.getMinMeasureScaleValue() * newMeasurementUnit.getMultiple());
        }
        if (measureScaleEmbeddable.getMaxMeasureScaleUnit().getId().equals(id)) {
            Assertions.assertThat(measureScaleEmbeddable.getMaxMeasureScaleAbsoluteValueInTest()).isEqualTo(measureScaleEmbeddable.getMaxMeasureScaleValue() * newMeasurementUnit.getMultiple());
        }
    }

    logger.debug("17. 断言相关参量");
    List parameters = parameterRepository.findAllByAccuracy_MinAccuracyUnit_IdOrAccuracy_MaxAccuracyUnit_IdOrMeasureScale_MinMeasureScaleUnit_IdOrMeasureScale_MaxMeasureScaleUnit_Id(id, id, id, id);
    Assertions.assertThat(parameters.size()).isEqualTo(6);

    for (Parameter parameter : parameters) {
        AccuracyEmbeddable accuracyEmbeddable = parameter.getAccuracy();
        MeasureScaleEmbeddable measureScaleEmbeddable = parameter.getMeasureScale();
        if (accuracyEmbeddable.getMinAccuracyUnit().getId().equals(id)) {
            Assertions.assertThat(accuracyEmbeddable.getMinAccuracyAbsoluteValueInTest()).isEqualTo(accuracyEmbeddable.getMinAccuracyValue() * newMeasurementUnit.getMultiple());
        }
        if (accuracyEmbeddable.getMaxAccuracyUnit().getId().equals(id)) {
            Assertions.assertThat(accuracyEmbeddable.getMaxAccuracyAbsoluteValueInTest()).isEqualTo(accuracyEmbeddable.getMaxAccuracyValue() * newMeasurementUnit.getMultiple());
        }
        if (measureScaleEmbeddable.getMinMeasureScaleUnit().getId().equals(id)) {
            Assertions.assertThat(measureScaleEmbeddable.getMinMeasureScaleAbsoluteValueInTest()).isEqualTo(measureScaleEmbeddable.getMinMeasureScaleValue() * newMeasurementUnit.getMultiple());
        }
        if (measureScaleEmbeddable.getMaxMeasureScaleUnit().getId().equals(id)) {
            Assertions.assertThat(measureScaleEmbeddable.getMaxMeasureScaleAbsoluteValueInTest()).isEqualTo(measureScaleEmbeddable.getMaxMeasureScaleValue() * newMeasurementUnit.getMultiple());
        }
    }

    logger.debug("18. 断言相关附加参量");
    List additionalParameters = additionalParameterRepository.findAllByMeasureScale_MinMeasureScaleUnit_IdOrMeasureScale_MaxMeasureScaleUnit_Id(id, id);
    Assertions.assertThat(additionalParameters.size()).isEqualTo(3);

    for (AdditionalParameter additionalParameter : additionalParameters) {
        MeasureScaleEmbeddable measureScaleEmbeddable = additionalParameter.getMeasureScale();
        if (measureScaleEmbeddable.getMinMeasureScaleUnit().getId().equals(id)) {
            Assertions.assertThat(measureScaleEmbeddable.getMinMeasureScaleAbsoluteValueInTest()).isEqualTo(measureScaleEmbeddable.getMinMeasureScaleValue() * newMeasurementUnit.getMultiple());
        }
        if (measureScaleEmbeddable.getMaxMeasureScaleUnit().getId().equals(id)) {
            Assertions.assertThat(measureScaleEmbeddable.getMaxMeasureScaleAbsoluteValueInTest()).isEqualTo(measureScaleEmbeddable.getMaxMeasureScaleValue() * newMeasurementUnit.getMultiple());
        }
    }
}

/**
 * 获取一个精度内嵌实体
 */
private AccuracyEmbeddable getOneAccuracyEmbeddable() {
    logger.debug("获取计量单位");
    MeasurementUnit otherMeasurementUnit = measurementUnitService.getOneSavedMeasurementUnit();

    logger.debug("构造精度内嵌实体");
    AccuracyEmbeddable accuracyEmbeddable = new AccuracyEmbeddable();
    accuracyEmbeddable.setMinAccuracyValue(1.0f);
    accuracyEmbeddable.setMinAccuracyUnit(otherMeasurementUnit);
    accuracyEmbeddable.setMaxAccuracyValue(10.0f);
    accuracyEmbeddable.setMaxAccuracyUnit(otherMeasurementUnit);

    return accuracyEmbeddable;
}

/**
 * 获取内嵌测量范围
 */
private MeasureScaleEmbeddable getOneMeasureScaleEmbeddable() {
    logger.debug("获取计量单位");
    MeasurementUnit otherMeasurementUnit = measurementUnitService.getOneSavedMeasurementUnit();

    logger.debug("构造测量范围内嵌实体");
    MeasureScaleEmbeddable measureScaleEmbeddable = new MeasureScaleEmbeddable();
    measureScaleEmbeddable.setMinMeasureScaleValue(1.0f);
    measureScaleEmbeddable.setMinMeasureScaleUnit(otherMeasurementUnit);
    measureScaleEmbeddable.setMaxMeasureScaleValue(10.0f);
    measureScaleEmbeddable.setMaxMeasureScaleUnit(otherMeasurementUnit);

    return measureScaleEmbeddable;
}

测试通过了,但是并不是我想要的。

因为我在执行该测试时,还没有写修改附加参量的方法。本测试是期待不通过的。

分析

具体内部怎么运行的不知道,但是应该是前面的引用修改状态,后面的就跟着变了。

之前为了少写几行代码,非强检器具、参量、附加参量这三个用的是同一个测量范围对象,不知道具体的执行过程,但是猜想应该是这东西的问题。

尝试写了一下克隆方法,每次都克隆一个新对象。

网上写的克隆方法,总觉得不好,最后还要强转。

在实体中写的克隆对象的方法,就是new一个然后返回去呗。

public AccuracyEmbeddable cloneAccuracyEmbeddable() {
    AccuracyEmbeddable accuracyEmbeddable = new AccuracyEmbeddable();
    accuracyEmbeddable.setMinAccuracyValue(this.minAccuracyValue);
    accuracyEmbeddable.setMinAccuracyUnit(this.minAccuracyUnit);
    accuracyEmbeddable.setMaxAccuracyValue(this.maxAccuracyValue);
    accuracyEmbeddable.setMaxAccuracyUnit(this.maxAccuracyUnit);
    accuracyEmbeddable.prePersist();
    return accuracyEmbeddable;
}

public MeasureScaleEmbeddable cloneMeasureScaleEmbeddable() {
    MeasureScaleEmbeddable measureScaleEmbeddable = new MeasureScaleEmbeddable();
    measureScaleEmbeddable.setMinMeasureScaleValue(this.minMeasureScaleValue);
    measureScaleEmbeddable.setMinMeasureScaleUnit(this.minMeasureScaleUnit);
    measureScaleEmbeddable.setMaxMeasureScaleValue(this.maxMeasureScaleValue);
    measureScaleEmbeddable.setMaxMeasureScaleUnit(this.maxMeasureScaleUnit);
    measureScaleEmbeddable.prePersist();
    return measureScaleEmbeddable;
}

然后就用clone方法获取新对象并设置。

additionalParameter1.setMeasureScale(measureScaleEmbeddable1.cloneMeasureScaleEmbeddable());
additionalParameter2.setMeasureScale(measureScaleEmbeddable2.cloneMeasureScaleEmbeddable());
additionalParameter3.setMeasureScale(measureScaleEmbeddable3.cloneMeasureScaleEmbeddable());

再次执行测试,出现了预期中的错误,证明就是对象引用的问题。

总结

测试驱动开发,如果我是写完方法再写测试,这应该是一个能通过却有问题的测试,而我却不知道。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/8872.html

相关文章

  • js克隆一个对象,支持循环引用的克隆

    摘要:判断参数是否为待判断的参数克隆一个对象要克隆的目标对象克隆节点,绑定事件的有问题,暂不处理克隆在当前作用域,在全局克隆其它对象,通过识别复制后的对象与原对象是否相同来决定传不传参数,像数组是不能传参数的使用防止对象重写了方法支持节点克隆 (function(){ var toString=Object.prototype.toString,gObj={},cloneHelper=f...

    fai1017 评论0 收藏0
  • JavaScript对象克隆

    摘要:原始类型对象指的是字符串数值布尔值,引用类型对象指的是数组对象函数。既然对象分为这两类,他们的复制克隆也是有差别的。总结根据上面的情况,另外,克隆引用对象必须采用完整克隆深度克隆,包括对象的值也是一个对象也要进行完整克隆深度克隆。 前言 之前有人问我如何克隆一个JS对象,我当时没答上来;过后我查资料弄懂了这个问题,现在整理成文。 正文 JavaScript的一切实例都是对象,但他们也分...

    douzifly 评论0 收藏0
  • 【转】JavaScript 对象的深度克隆

    摘要:在聊以下简称深度克隆之前,我们先来了解一下中对象的组成。克隆或者拷贝分为种浅度克隆深度克隆。浅度克隆基本类型为值传递,对象仍为引用传递。 该文转载自http://www.cnblogs.com/zichi/p/4568150.html,有部分修改。 在聊JavaScript(以下简称js)深度克隆之前,我们先来了解一下js中对象的组成。在 js 中一切实例皆是对象,具体分为 原始类型 ...

    JowayYoung 评论0 收藏0
  • ES6时代,你真的会克隆对象吗(二)

    摘要:多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。比如,表达式会返回,因为属性得到的仅仅是构造函数,而且是可以被手动更改的,只是返回的构造函数的名字,它并不返回类名。 原文:ES6时代,你真的会克隆对象吗(二) 上一篇,我们从Symbol和是否可枚举以及属性描述符的角度分析了ES6下怎么浅拷贝一个对象,发表在掘金和segmentfault上(...

    BoYang 评论0 收藏0
  • Java 作者谈克隆方法的实现

    摘要:不合规的代码示例合规解决方案参阅复制构造函数与克隆也可以参阅应该实现克隆覆盖的类应为并调用下面为引文翻译谈设计与作者的对话,作者首次在上发表,年月日复制构造函数与克隆在你的书中,你建议使用复制构造函数而不是实现和编写。 今天在用 sonar 审核代码, 偶然看到下面的提示:showImg(https://segmentfault.com/img/bVbqioZ?w=858&h=116)...

    gaomysion 评论0 收藏0
  • js对象详解(JavaScript对象深度剖析,深度理解js对象)

    摘要:对象详解对象深度剖析,深度理解对象这算是酝酿很久的一篇文章了。用空构造函数设置类名每个对象都共享相同属性每个对象共享一个方法版本,省内存。 js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了。 JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕。 平时发的文章基本都是开发中遇到的问题和对...

    CatalpaFlat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<