The document provides an introduction to test-driven development (TDD) and testing with JavaScript and React. It discusses the benefits of TDD such as early bug detection, clear code, and living documentation. It also covers frustrations with TDD. The document demonstrates TDD by incrementally developing a calculator app through testing examples, showing the red-green-refactor process and handling invalid inputs. It emphasizes that TDD helps improve code quality and avoids bugs but is not a "silver bullet" solution.
14. Essentials:
● React
● Mocha - Test Framework
● Chai - Assertion Library
● Sinon - Mock Library
● Enzyme - React Test Utility
The Stack
15. Story
Given
Numerical values separated by +
symbols are entered in the
equation field
When
User clicks the equal button
Then
Sum of all numerical values
should display to the right of the
equal button
18. 7
We connect the digital and physical worlds
export class Math1 {
static parseEquation(equation) {
const addValues = equation.split('+');
let sum = 0;
addValues.forEach((value) => {
sum += value;
});
return sum;
}
}
20. 7
We connect the digital and physical worlds
export class Math1 {
static parseEquation(equation) {
const addValues = equation.split('+');
let sum = 0;
addValues.forEach((value) => {
sum += value;
});
return sum;
}
}
0 + “1 ” + “ 1” = “01 1”
21. We connect the digital and physical worlds
export class Math2 {
static parseEquation(equation) {
const addValues = equation.split('+');
let sum = 0;
addValues.forEach((value) => {
sum += parseInt(value.trim());
});
return sum;
}
}
23. We connect the digital and physical worlds
describe('test addition component', () => {
let subject;
let mockParseEquation;
beforeEach(() => {
//Arrange
subject = shallow(<Calculator/>);
mockParseEquation = sinon.stub(math, "parseEquation");
});
afterEach(() => {
mockParseEquation.restore();
});
it('calls math function on click with correct values', () => {
//Arrange
subject.setState({equation:'1 + 1'})
//Act
subject.find('button').simulate('click');
//Assert
expect(mockParseEquation.getCall(0).args[0]).to.equal('1 + 1');
});
...
24. We connect the digital and physical worlds
...
it('displays result of math utility', () => {
//Arrange
mockParseEquation.returns(2);
//Act
subject.find('button').simulate('click');
//Assert
const resultText = subject.find('.result').text();
expect(resultText).to.equal('2');
});
});
25. We connect the digital and physical worlds
calculateValue() {
const additionSum = math.parseEquation(this.state.equation);
this.setState({calculatedResult: additionSum});
}
render() {
return (
<div>
<input
value={this.state.equation}
onChange={this.handleValueChange} />
<button onClick={this.calculateValue}>
=
</button>
<label className="result">{this.state.calculatedResult}</label>
</div>
);
}
30. We connect the digital and physical worlds
export class Math2 {
static parseEquation(equation) {
const addValues = equation.split('+');
let sum = 0;
addValues.forEach((value) => {
sum += parseInt(value.trim());
});
return sum;
}
}
1 + NaN = NaN
31. We connect the digital and physical worlds
it('invalid input between numbers', () => {
//Arrange/Act
const rtnValue = math.parseEquation('1 + 123asdf453');
//Assert
expect(rtnValue).to.be.NaN;
});
1 + 123 = 124
32. We connect the digital and physical worlds
// attempt 3
export class Math3 {
static parseEquation(equation) {
const addValues = equation.split('+');
let sum = 0;
const invalidInput = addValues.some((value) => {
const trimValue = value.trim();
if(!isNaN(parseInt(trimValue)) && isFinite(trimValue)) {
return true;
} else {
sum += parseInt(trimValue);
return false;
}
});
return invalidInput ? NaN : sum;
}
}