Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing of extremely trivial methods (yes or no)

Suppose you have a method:

public void Save(Entity data)
{
    this.repositoryIocInstance.EntitySave(data);
}

Would you write a unit test at all?

public void TestSave()
{
    // arrange
    Mock<EntityRepository> repo = new Mock<EntityRepository>();
    repo.Setup(m => m.EntitySave(It.IsAny<Entity>());

    // act
    MyClass c = new MyClass(repo.Object);
    c.Save(new Entity());

    // assert
    repo.Verify(m => EntitySave(It.IsAny<Entity>()), Times.Once());
}

Because later on if you do change method's implementation to do more "complex" stuff like:

public void Save(Entity data)
{
    if (this.repositoryIocInstance.Exists(data))
    {
        this.repositoryIocInstance.Update(data);
    }
    else
    {
        this.repositoryIocInstance.Create(data);
    }
}

...your unit test would fail but it probably wouldn't break your application...

Question

Should I even bother creating unit tests on methods that don't have any return types* or **don't change anything outside of internal mock?

like image 431
Robert Koritnik Avatar asked Aug 03 '09 10:08

Robert Koritnik


People also ask

Should you test trivial code?

Test trivial code only when you need toHave mechanisms in place to evaluate the quality of the test suite (and do it often).

What should not be unit tested?

Do not test anything that does not involve logic. For example: If there is a method in the service layer which simply invokes another method in the data access layer, don't test it.

Which method is used for unit testing?

Unit tests can be performed manually or automated. Those employing a manual method may have an instinctual document made detailing each step in the process; however, automated testing is the more common method to unit tests. Automated approaches commonly use a testing framework to develop test cases.

Should unit tests test all methods?

The answer to the more general question is yes, you should unit test everything you can. Doing so creates a legacy for later so changes down the road can be done with peace of mind. It ensures that your code works as expected.


2 Answers

Ask yourself two questions. "What is the manual equivalent of this unit test?" and "is it worth automating?". In your case it would be something like:

What is manual equivalent? - start debugger - step into "Save" method - step into next, make sure you're inside IRepository.EntitySave implementation

Is it worth automating? My answer is "no". It is 100% obvious from the code. From hundreds of similar waste tests I didn't see a single which would turn out to be useful.

like image 76
KolA Avatar answered Nov 13 '22 23:11

KolA


It's true your test is depending on your implementation, which is something you should avoid (though it is not really that simple sometimes...) and is not necessarily bad. But these kind of tests are expected to break even if your change doesn't break the code.

You could have many approaches to this:

  • Create a test that really goes to the database and check if the state was changed as expected (it won't be a unit test anymore)
  • Create a test object that fakes a database and do operations in-memory (another implementation for your repositoryIocInstance), and verify the state was changed as expected. Changes to the repository interface would incurr in changes to this object as well. But your interfaces shouldn't be changing much, right?
  • See all of this as too expensive, and use your approach, which may incur on unnecessarily breaking tests later (but once the chance is low, it is ok to take the risk)
like image 20
Samuel Carrijo Avatar answered Nov 14 '22 00:11

Samuel Carrijo