1

I'm trying to test a component that shows a button if the record my component is sitting on has a certain field populated, but I can't get the tests working: the button is always created, regardless of the data in my mock get record call.

This is my js:

import { LightningElement, api, wire } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import TRANSACTION_ID_FIELD from '@salesforce/schema/Opportunity.Transaction_Id__c';

export default class MyComponent extends LightningElement {
  @api recordId;
  @wire(
    getRecord,
    { recordId: '$recordId', fields: [TRANSACTION_ID_FIELD] })
    record;
  get transactionIdValue() {
    return getFieldValue(this.record.data, TRANSACTION_ID_FIELD);
  }

My html:

<template>
  <template if:false={transactionIdValue}>
    <lightning-button
      label="my button"
      title="My Button"
      class="slds-m-left_x-small"
    ></lightning-button>
  </template>
  <template if:true={transactionIdValue}>
    <p>Transaction ID already exists</p>
  </template>
</template>

My test (which fails, because the button is rendered):

import { createElement } from 'lwc';
import MyComponent from 'c/myComponent';
import { registerLdsTestWireAdapter } from '@salesforce/sfdx-lwc-jest';
import { getRecord } from 'lightning/uiRecordApi';

const mockGetRecord = require('./data/getRecord.json');
const getRecordWireAdapter = registerLdsTestWireAdapter (getRecord);

const flushPromises = () => {
  // eslint-disable-next-line no-undef
  return new Promise(resolve => setImmediate(resolve));
}

describe('button rendering test', () => {
  afterEach(() => {
    while (document.body.firstChild) {
      document.body.removeChild(document.body.firstChild);
    }
  });
  it('does not display the button when there is a transaction ID', () => {
    const element = createElement('c-my-component', {
      is: MyComponent
    });
    // I added this to try and force the transaction Id to be set,
    // but it still renders the button anyway
    element.transactionIdValue = "some value"
    document.body.appendChild(element);
    getRecordWireAdapter.emit(mockGetRecord);

    return flushPromises().then(() => {
      const button = element.shadowRoot.querySelector('lightning-button');
      expect(button).toBeNull();
    });
  });
});

And my getRecord.json:

{
  "apiName": "Opportunity",
  "childRelationships": {},
  "eTag": "b08d5a3a1cd80f4c2437e4eca5d1fe61",
  "fields": {
    "Transaction_ID__c": {
      "displayValue": null,
      "value": "test id"
    }
  }
}

After experimenting for a bit I realised that it doesn't matter what my getRecord.json contains, or if I call the getRecordWireAdapter.emit() at all: the shadowRoot will always have the button rendered. I do not have experience testing front end in general, so I'm puzzled and I feel like I'm missing something quite obvious, but I can't figure out what.

Any pointer on how to proceed in the right direction would be greatly appreciated, because I'm ready to give up testing and call it a day...

0

It seems you are not registering the test wire adapter:

const getRecordWireAdapter = registerLdsTestWireAdapter(getRecord);

You can look a complete example in: https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.unit_testing_using_wire_utility

| improve this answer | |
  • Hey, thanks for your help, but actually I had that in my code, I just must've accidentally edited it out when anonymising it for this question, so that wasn't the issue. I edited my question to include it back. – vitorm Nov 6 '19 at 1:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.