Testing editing view model directly - detect change

Hi people,

I new to Aurelia and about to figure out how to structure my tests. Is it a good/bad practice to directly access the vm and change things there? I want to keep my test setup short and concise and want to do for example this:

describe('Test', () => {
    let component: ComponentTester;
    let parent;

    beforeEach(async () => {
        parent = {
            vm: {}
        };
        component = StageComponent.withResources([
            './resources/elements/controls/comp-under-test'
        ])
            .inView(
                '<comp-under-test view-model.ref="vm"></comp-under-test>'
            )
            .boundTo(parent);
        await component.create(bootstrap);
    });

    fit('test edit mode', async () => {
        parent.vm.editMode = true;
        // trigger change detection!!!

        const button = await component.waitForElements('.cancel-button');
        button.should.be.defined();
    });

    afterEach(() => {
        if (component) {
            component.dispose();
        }
    });
});
1 Like

I am trying to do this too. Sadly, I didn’t manage to make it work. The best I got was by doing component.viewModel.value = 'newValue'. With jest, I get (by putting a console.log in valueChanged): Attempted to log "nausnratuernstauiet.

This looks like the path to dig. But I don’t manage to wait for the update to be complete. I haven’t found anything on the test model that could help me do that.

But at least with that, the jest snapshot is correctly updated.

Does someone have more information on this?

1 Like

That’s what Aurelia designed to do, Aurelia core libs test code mutates model directly too.

I don’t think taskQueue.flushMicroTaskQueue(); is needed for your test, but the delay new Promise(r => setTimeout(r, 1)) is required for Aurelia to render the changes to DOM before your test continue.

1 Like

thanks for the reply!

I tried this out and it kind of works. But I am not totally sure if this is the proper way. Do you have maybe some good test examples from the original source or another project?

In the code snippe you shared the autor says:
// This is horrible, but the only way I found to get things working
return new Promise(r => setTimeout(r, 1));

1 Like

Unfortunately this is testing, you have to delay to let DOM to render.

You can dry it up with

function delay() {
  return new Promise(r => setTimeout(r, 1));
}

...
.then(delay)
.then(() => ...)
.then(delay)
.then(() => ...)

Or use async/await syntax

async function delay() {
  return new Promise(r => setTimeout(r, 1));
}

...
await delay();
...
await delay();
...

In Aurelia test code, there is a utility called createAssertionQueue, it does the same thing. I recommend to use the latest async/await syntax instead.

1 Like