I have heard multiple theories on this and was wondering if anyone with experience know what works best. FYI, the following code is JavaScript through the idea in general.
There are 2 theories I hear most often on unit testing.
- A unit test should only test one logical concept which might include multiple assertions.
- There should only be one reason for a unit test to fail therefore there should only be one assertion.
The first one could have a unit test written like:
it('should set default values', function() {
nagRestSchemaManager.add('user', userModelOptions);
var model = nagRestBaseModel.create('user');
expect(model.toJson()).toEqual({});
expect(model.getDirtyProperties()).toEqual([]);
expect(model.isDirty()).toBe(false);
expect(model.isSynced()).toBe(false);
});
The second one could have the same unit test written like:
it('should set json to empty object by default', function() {
nagRestSchemaManager.add('user', userModelOptions);
var model = nagRestBaseModel.create('user');
expect(model.toJson()).toEqual({});
});
it('should set dirty properties to empty array by default', function() {
nagRestSchemaManager.add('user', userModelOptions);
var model = nagRestBaseModel.create('user');
expect(model.getDirtyProperties()).toEqual([]);
});
it('should evaluate isDirty() as false by default', function() {
nagRestSchemaManager.add('user', userModelOptions);
var model = nagRestBaseModel.create('user');
expect(model.isDirty()).toBe(false);
});
it('should evaluate isSynced() as false by default', function() {
nagRestSchemaManager.add('user', userModelOptions);
var model = nagRestBaseModel.create('user');
expect(model.isSynced()).toBe(false);
});
Now I can see the arguments for both. The first requires less code to be written. The second will quickly test you what is failing (with the first you would have to go into the code to see the exact failing reason).
My question is, in practice, is one generally preferred over the other?