Почему исходный элемент в моем массиве перезаписывается с помощью Object.assign? - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть модульный тест, который дает то, чего я не ожидал:

Предыстория: я делаю простой список задач с Angular / тест-ориентированной разработкой.

Проблема: когда я вызываю editTask для элемента в массиве, он меняет значение элемента. Но я не вижу, как это изменилось в исходном массиве, потому что исходный массив никогда не доступен в методе, который я тестирую. Пожалуйста, помогите мне подключиться КАК оригинальный массив изменяется? Кажется, Object.assign делает это, но почему?

 describe('editTask', () => {
    it('should update the task by id', () => {
      const dummyTask1 = { id: 1, name: 'test', status: false };
      service.tasks.push(dummyTask1); //refers to TestBed.get(TaskService)
      const id = 1;
      const values = { name: 'cat', status: false };

      service.editTask(id, values);
      console.log(service.tasks); // why does this log this object? [Object{id: 1, name: 'cat', status: false}]
      expect(service.tasks[0].name).toEqual(values.name); // Test passes
    });
  });

Вот метод, который я тестирую:

  editTask(id, values) {
    const task = this.getTask(id);

    if (!task) {
      return;
    }

    Object.assign(task, values); //How does this line change the array?

    return task;
  }

  getTask(id: number) {
    return this.tasks.filter(task => task.id === id).pop(); //is this altering the original array somehow?
  }

Если необходимо, вот полный сервис Angular:

export class TaskService {
  tasks: any = [];
  lastId = 0;

  constructor() { }

  addTask(task) {
    if (!task.id) {
      task.id = this.lastId + 1;
    }

    this.tasks.push(task);
  }

  editTask(id, values) {
    const task = this.getTask(id);

    if (!task) {
      return;
    }

    Object.assign(task, values);

    return task;
  }

  deleteTask(id: number) {
    this.tasks = this.tasks.filter(task => task.id !== id);
  }

  toggleStatus(task) {
    const updatedTask = this.editTask(task.id, { status: !task.status});

    return updatedTask;
  }

  getTasks() {
    return of(this.tasks);
  }

  getTask(id: number) {
    return this.tasks.filter(task => task.id === id).pop();
  }
}

Вот репозиторий github: https://github.com/capozzic1/todo-tdd

1 Ответ

0 голосов
/ 06 сентября 2018

Метод getTask() получает ссылку на элемент в массиве с использованием метода filter () .

Затем используется Object.assign () , чтобы изменить свойства элемента. Метод Object.assign () используется для копирования значений всех перечисляемых собственных свойств из одного или нескольких исходных объектов в целевой объект. Он вернет целевой объект.

Так что теперь значения ссылки в памяти предмета изменены. Поскольку это ссылка в памяти, вы увидите, что оригинальный элемент изменяется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...