Как проверить реакцию mobx? - PullRequest
0 голосов
/ 08 декабря 2018

Примечание : это не настоящее приложение, а искаженная версия проблемы.

У меня есть простое приложение, поддельное Todo, которое использует @computed, чтобы получить значение TodoItemComputed.isSelected:

import { computed, observable, action } from 'mobx';

export class TodoItemComputed {
    readonly id: string;
    readonly list: TodoListComputed;
    constructor(id: string, list: TodoListComputed) {
        this.id = id;
        this.list = list;
    }
    // ** This is the attribute we are interested in and we want to test!
    @computed
    get isSelected() {
        return this.id === this.list.selectedId;
    }
}

export class TodoListComputed {
    @observable.shallow
    private serverData: string[] = [];

    @observable
    selectedId = '';

    @action
    setServerData(data: string[]) {
        this.serverData = data;
    }
    @action
    setSelected(id: string) {
        this.selectedId = id;
    }
    @computed
    get todoItems() {
        return this.serverData.map(d => new TodoItemComputed(d, this));
    }
}

Тестирование TodoItemComputed.isSelected Я мог бы сделать что-то вроде этого:

import { TodoListComputed } from '../TodoExample';

// Using jesthere, but the test framework should not matter...
describe('isSelected', function() {
    it('should have no Item selected initially', function() {
        const todoList = new TodoListComputed();
        todoList.setServerData(['foo', 'bar']);
        expect(todoList.todoItems[0].isSelected).toBe(false);
        expect(todoList.todoItems[1].isSelected).toBe(false);
    });
    it('should select the correct item', function() {
        const todoList = new TodoListComputed();
        todoList.setServerData(['foo', 'bar']);
        todoList.setSelected('bar');
        expect(todoList.todoItems[0].isSelected).toBe(false);
        expect(todoList.todoItems[1].isSelected).toBe(true);
    });
});

По некоторым причинам, я должен реорганизовать свое приложение и использовать реакции вместо вычисленных (дляпример, потому что мне нужно отобразить 10000 элементов, а выбор быстро изменился, и при вызове TodoListComputed.setSelected все вычисления были перезапущены для всех элементов).

Поэтому я изменяю его на использование reaction (кажется, что когдаЯ использую autorun Я могу использовать те же тесты, что и для computed версии):

import { autorun, computed, observable, action } from 'mobx';

export class TodoItemReaction {
    readonly id: string;
    @observable
    isSelected = false;

    constructor(id: string) {
        this.id = id;
    }
    @action
    setSelected(isSelected: boolean) {
        this.isSelected = isSelected;
    }
}

export class TodoListReaction {
    @observable.shallow
    private serverData: string[] = [];
    @observable
    selectedId = '';

    constructor() {
        reaction(
            () => [this.setSelected, this.todoItems],
            () => {
                this.todoItems.forEach(t => {
                    t.setSelected(t.id === this.selectedId);
                });
            }
        );
    }

    @action
    setServerData(data: string[]) {
        this.serverData = data;
    }
    @action
    setSelected(id: string) {
        this.selectedId = id;
    }
    @computed
    get todoItems() {
        return this.serverData.map(d => new TodoItemReaction(d));
    }
}

Вопрос : Как проверить версию autorun?

Бонусный вопрос : Как проверить код, который не имеет значения, если я использую autorun или computed?

...