Reputation: 472
Let's say I have the following class:
class Foo {
public a( a, b ) {
return this._execute( {a,b} );
}
public b( a ) {
return this._execute( a );
}
private _execute( a ) {
if ( ...condition... ) {
throw new Error("Validation failed!");
}
return a;
}
}
And I'd like to prepare a set of unit tests for it. Should I add a test that should check the condition
both for a()
and b()
? Maybe only one method should check it? If so, which one? Or maybe I should use some other approach?
My goal is to reduce the number of unit tests and in this case, I've got the same test for both methods.
Upvotes: 0
Views: 45
Reputation: 29090
You can split your code into components that are dealing with one thing only:
class Foo {
private _validator;
constructor(validator) {
this._validator = validator;
}
public a( a, b ) {
return this._validator.validate( {a,b} );
}
public b( a ) {
return this._validator.validate( a );
}
}
class MyValidator {
public validate( value ) {
if ( /*...condition...*/ ) {
throw new Error("Validation failed!");
}
return value;
}
}
Now you can test MyValidator
as much as you want to make sure it handles inputs as you want. The tests will be applicable for both Foo#a
and Foo#b
.
What you want to do next is to verify that the methods do use the validator, so in a test setup you can create a mock validator and instantiate const foo = new Foo( mockValidator )
. Then the test can look like this:
test( "a() uses the validator", () => {
//arrange
const mockValidator = { validate: jest.fn() };
const foo = new Foo( mockValidator );
const value = "something";
//act
foo.a( value );
//assert
expect(mockValidator.validate).toHaveBeenCalledWith(value);
}
test( "a() does not swallow the validation error", () => {
//arrange
const mockValidator = { validate: () => { throw Error("mock") } };
const foo = new Foo( mockValidator );
//act + assert
expect(() => foo.a( "" )).toThrow();
}
Note: I'm using Jest for illustrative purposes. The same can be achieved using other testing libraries.
Upvotes: 1