I'd say over specification would be when you have a test
that has more details of what is happening in the
situation than a potential situation user must know is
happening.
for example, if you had this method:
public int Add(int a, int b) {
Logger.Log(LogLevel.Diagnostic, "Adding {0} and {1}", a,
b);
return a + b;
}
An overspecified test testing whether calling Add(3,5)
would give the result of 8 and would mock ILogger and
expect a call to Log. The user of this Add method should
reasonably expect that the method adds 3 and 5 together,
but should not expect that the method logs information
at a diagnostic level.
One of the most common examples of overspecified tests
I've personally encountered is misuse of mocks where a
stub (or similar) would suffice.
An (abstract) example would be a business component that
depends on a data access layer. A unit test ought to
verify that a business object is persisted properly by
calling the correct method in the data access layer, but
every other member invoked in the data access layer
should be ignored.
However, in such a scenario, many test developers
strictly define ALL expectations on the data access
layer, instead of only the single, relevant method.
I must confess to having fallen into this pit myself
back in around 2003-2004...
When the object you're testing doesn't have any real
responsibility but passes things off to other objects,
and so the whole test is a big mock expectation. I start
to think that my design is bad when I write these. It's
like I'm more worried about what's going on in the
inside than the outside.
Code example:
class Validator : IValidator {
public bool IsEntityValid(object entity) { }
}
class Repository : IRepository {
public object AddToCurrentTransaction(object entity) { }
}
Entity entity = new Entity(validator, repository);
entity.Save();
mockery.VerifyExpectationsHaveBeenMet();
}
The test is ok, but the problem is the entity here
shouldn't have a save method. It's not doing anything.
I'm overspecifying the exact steps it should take to
overcompensate for a poor design.
}