Reputation: 903
The following component ends up in an infinite re render loop during testing and I can't figure out why. It works just fine in the application and all it does is receive some data through an event bus, map it to something that can be used in a component
tags 'is' property and push that into an array.
<template>
<div id="notification-area">
<div v-for="(component, index) in notificationComponents" :key="index">
<component
:is="component.options"
:notification="component.notification"
/>
</div>
</div>
</template>
<script lang="ts">
import {Component, Inject, Vue} from "vue-property-decorator";
import {Notification, UserErrorNotification, InfoNotification} from "@/Notification";
import InfoNotificationView from "@/components/notifications/InfoNotificationView.vue";
import UserErrorNotificationView from "@/components/notifications/UserErrorNotificationView.vue";
import {ComponentOptions, DefaultComputed, DefaultData, DefaultMethods, PropsDefinition} from "vue/types/options";
type VueOptions = ComponentOptions<
Vue,
DefaultData<Vue>,
DefaultMethods<Vue>,
DefaultComputed,
PropsDefinition<Record<string, {}>>
>
interface NotificationComponent {
options: VueOptions;
notification: Notification;
}
@Component({})
export default class NotificationArea extends Vue {
@Inject('eventBus') private eventBus!: Vue;
private notificationComponents = [] as Array<NotificationComponent>;
private static asNotificationComponent(notification: UserErrorNotification | InfoNotification): NotificationComponent{
if (notification instanceof UserErrorNotification) {
return {options: new UserErrorNotificationView().$options, notification: notification}
}
return {options: new InfoNotificationView().$options, notification: notification}
}
created() {
this.eventBus.$on('notification', (notification: UserErrorNotification | InfoNotification) => {
this.notificationComponents.push(NotificationArea.asNotificationComponent(notification));
})
}
}
</script>
InfoNotificationView
and UserErrorNotificationView
are simple wrappers around a BAlert.
The following is the test that results in an out of memory exception.
describe("NotificationArea.vue", () => {
let wrapper: Wrapper<NotificationArea>;
beforeEach(() => {
wrapper = shallowMount(NotificationArea, {
provide: {
eventBus: new MockEventBus()
},
created() {}
});
});
it("renders the notifications correctly", async () => {
wrapper.setData({
notificationComponents: [successNotificationComponent, warningNotificationComponent]
});
await wrapper.vm.$nextTick() // <-- Here it hangs.
const infoNotification = wrapper.find("infonotificationview-stub");
expect(infoNotification.props('notification')).toBe(successNotificationComponent);
const userErrorNotification = wrapper.find("usererrornotificationview-stub")
expect(userErrorNotification.props("notification")).toBe(warningNotificationComponent);
});
});
Upvotes: 2
Views: 430
Reputation: 903
As it turns out, the problem was jest printing a very big object, since successNotificationComponent
contains a vue component.
I fixed it by putting a testId
into the notification during testing and checking for that.
Upvotes: 1