Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing - Am I doing it right?

Basically I have been programing for a little while and after finishing my last project can fully understand how much easier it would have been if I'd have done TDD. I guess I'm still not doing it strictly as I am still writing code then writing a test for it, I don't quite get how the test becomes before the code if you don't know what structures and how your storing data etc... but anyway...

Kind of hard to explain but basically lets say for example I have a Fruit objects with properties like id, color and cost. (All stored in textfile ignore completely any database logic etc)

    FruitID FruitName   FruitColor  FruitCost
    1         Apple       Red         1.2
    2         Apple       Green       1.4
    3         Apple       HalfHalf    1.5

This is all just for example. But lets say I have this is a collection of Fruit (it's a List<Fruit>) objects in this structure. And my logic will say to reorder the fruitids in the collection if a fruit is deleted (this is just how the solution needs to be).

E.g. if 1 is deleted, object 2 takes fruit id 1, object 3 takes fruit id2.

Now I want to test the code ive written which does the reordering, etc.

How can I set this up to do the test?


Here is where I've got so far. Basically I have fruitManager class with all the methods, like deletefruit, etc. It has the list usually but Ive changed hte method to test it so that it accepts a list, and the info on the fruit to delete, then returns the list.

Unit-testing wise: Am I basically doing this the right way, or have I got the wrong idea? and then I test deleting different valued objects / datasets to ensure method is working properly.


[Test]
public void DeleteFruit()
{
    var fruitList = CreateFruitList();
    var fm = new FruitManager();

    var resultList = fm.DeleteFruitTest("Apple", 2, fruitList);

    //Assert that fruitobject with x properties is not in list ? how
}

private static List<Fruit> CreateFruitList()
{
    //Build test data
    var f01 = new Fruit {Name = "Apple",Id = 1, etc...};
    var f02 = new Fruit {Name = "Apple",Id = 2, etc...};
    var f03 = new Fruit {Name = "Apple",Id = 3, etc...};

    var fruitList = new List<Fruit> {f01, f02, f03};
    return fruitList;
}
like image 441
baron Avatar asked May 05 '10 09:05

baron


People also ask

Are unit tests actually useful?

Unit testing ensures that all code meets quality standards before it's deployed. This ensures a reliable engineering environment where quality is paramount. Over the course of the product development life cycle, unit testing saves time and money, and helps developers write better code, more efficiently.


1 Answers

If you don't see what test you should start with, it's probably that you didn't think of what your functionality should do in simple terms. Try to imagine a prioritized list of basic behaviors that are expected.

What's the first thing you would expect from a Delete() Method ? If you were to ship the Delete "product" in 10 minutes, what would be the non-negotiable behaviour included ? Well... probably that it deletes the element.

So :

1) [Test]
public void Fruit_Is_Removed_From_List_When_Deleted()

When that test is written, go through the whole TDD loop (execute test => red ; write just enough code to make it pass => green ; refactor => green)

Next important thing related to this is that the method shouldn't modify the list if the fruit passed as an argument is not in the list. So next test could be :

2) [Test]
public void Invalid_Fruit_Changes_Nothing_When_Deleted()

Next thing you specified is that ids should be rearranged when a fruit is deleted :

3) [Test]
public void Fruit_Ids_Are_Reordered_When_Fruit_Is_Deleted()

What to put in that test ? Well, just set up a basic but representative context that will prove your method behaves as expected.

For example, create a list of 4 fruits, delete the first and check one by one that the 3 remaining fruits ids are reordered properly. That would pretty well cover the basic scenario.

Then you could create unit tests for error or borderline cases :

4) [Test]
public void Fruit_Ids_Arent_Reordered_When_Last_Fruit_Is_Deleted()

5) [Test]
[ExpectedException]
public void Exception_Is_Thrown_When_Fruit_List_Is_Empty()

...

like image 74
guillaume31 Avatar answered Sep 19 '22 03:09

guillaume31