Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
1
rated 0 times [  4] [ 3]  / answers: 1 / hits: 15691  / 5 Years ago, mon, april 15, 2019, 12:00:00

I am trying to mock this.ref.current.value as part of a test of a function in my React component.
Currently current is null because I am doing a shallow mount of my component. I am trying to find a way to mock what current.value returns for my ref so that I can test another part of the function, what the refs value is doesn't actually matter for this test.



Actual function:



copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = this[`${selectedInput}`].current.value;

// copy to clipboard
navigator.clipboard.writeText(copyText);
};


Test code:



it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<Alert {...props} />);

component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');

expect(navigator.clipboard.writeText).toHaveBeenCalled();
});


Test failure:



TypeError: Cannot read property 'value' of null

50 | // get and select the input value
> 51 | const copyText = this[`${selectedInput}`].current.value;


Is there any way to do this? I care about testing that navigator.clipboard was called not what it was called with.



Updating because I've changed my code to use this.ref instead of stringRefName
Actual function:



copyDefinitionTarget = selectedInput => () => {
// get and select the input value
const copyText = selectedInput.current.value;
// copy to clipboard
navigator.clipboard.writeText(copyText);
};


Test code:



it('calls navigator.clipboard appropriately to copy the text in copyDefinitionTarget', () => {
component = shallow(<Alert {...props} />);
instance = component.instance();

// we are clicking on the first Alert Item
// so mock that ref specifically
instance.firstNameRef = {
current: {
value: 'stuff'
}
};

component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');

expect(navigator.clipboard.writeText).toHaveBeenCalled();
});


Function call:



<Item
inputRef={this.firstNameRef}
inputValue={`${realmName}`}
copyDefinitionTarget={this.copyDefinitionTarget(this.firstNameRef)}
/>

More From » reactjs

 Answers
-4

You could go ahead and do something like this:



const component = shallow(<Alert {...props} />);
const selectedInput = 'ref';
component.instance()[selectedInput] = {
current: {
value: 'stuff'
}
}
navigator.clipboard = {writeText: jest.fn()}
component
.dive()
.find('Item')
.dive()
.find('Button')
.simulate('click');
expect(navigator.clipboard.writeText).toHaveBeenCalled();


Note: I am not sure what kind of string selectedInput should be, you could pass any string which is appropriate according to your real component code.



Since the ref exists as a instance property on the component, you can just pass any object you wish as long as it looks like current.value, then you can replace the copy function with a mock, simulate the click and then see if writeText was called.


[#52238] Wednesday, April 10, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
keric

Total Points: 572
Total Questions: 93
Total Answers: 97

Location: Cyprus
Member since Mon, Oct 24, 2022
2 Years ago
;