One of my biggest areas of struggle is in writing unit tests.
I enjoy all of the mocking frameworks, like Moq and Automoq, but I find that after mocking up so many interfaces, I question whether the unit tests have value.
As an example, I was recently writing unit tests for a bit of code that utilized an IRepository
var loginRepoMock = new Mock<IRepository<LoginAttempt>>(); var loginRecords = new List<LoginAttempt>() { new LoginAttempt() { Id = 1, UserName = "good.user", FailedAttempts = 0 }, new LoginAttempt() { Id = 2, UserName = "bad.user", FailedAttempts = 0 } }; loginRepoMock .Setup(x => x.Get(It.IsAny<Expression<Func<LoginAttempt, bool>>>(), It.IsAny<Func<IQueryable<LoginAttempt>, IOrderedQueryable<LoginAttempt>>>(), It.IsAny<string>())) .Returns<Expression<Func<LoginAttempt, bool>>, Func<IQueryable<LoginAttempt>, IOrderedQueryable<LoginAttempt>>, string> ((predicate, orderBy, includes) => { return loginRecords.AsQueryable().Where(predicate); }) .Verifiable(); loginRepoMock .Setup(x => x.Add(It.IsAny<LoginAttempt>())) .Callback((LoginAttempt loginAttempt) => { loginRecords.Add(loginAttempt); }) .Verifiable();
This worked well in that the consuming service could then be tested. However, it still feels weird to me. Did I add value through testing with a constrained data set?
Maybe this is just a philosophical issue, a desire to intertwine unit tests with integration tests, or a result of years of focusing on empirical integration testing. But, for me, it’s often times difficult to separate integration from unit testing.
I recall another article that I read not long ago that suggested testing as little as possible. For example, if the unit tests butt against Framework methods, or things that you have no control over, why spend the cycles necessary to think through how to test it?
At any rate, I think testing through code is sometimes a very nebulous thing and you can easily get lost in the weeds.