Reputation: 11
I am quite a beginner at unit testing and I got some failures that I do not know how to solve. I was trying to test my simple class Employee where I have static counter of created objects, so new employees can get consecutive numbers and default names like "Name1", "Name2" etc. Here is my default initiaiton block:
{
currentNr = ++count;
setName("Name"+currentNr);
setSurname("Surname"+currentNr);
}
I wrote one JUnit class with few methods. They are working fine but methods concerning counter are working only when I run them separately (they were also working when I saved them as separate tests, but it seemed messy having so many files). When I run the class with all the testing methods, counter is adding more object and I do not know why/when/where as test are independent. In testing methods I am creating an object and checking the counter with assertEqual. Looking for solutions I tried to work with @Before, @After, etc. but it was the same or maybe I do not know how to use it properly. My question is what could I do to have all the test methods working or what should I write in @Before method (I tried adding and deleting objects to ArrayList and/or setting to null). I guess it is not acceptable to have test working only when run separately. Any help will be appreciated. Thanks!
Upvotes: 1
Views: 1680
Reputation: 140641
The answer frenzykryger is giving a lot of valuable insight, but there is a bit more to it.
You should always look at your work with SOLID in mind. In your example, the "Single responsibility principle" can guide to a better solution. You see, good OO programming is about creating helpful abstractions. And some of the abstractions that you put into Employee simply don't belong there.
For example, one can create a class Employee to model a human being working for some company. So, employees are human beings, so probably they have names; and as they are part of an organization, yes, they might have an ID.
But: an employee gets an ID assigned! When you start at a new company, people don't come up and ask you: "please tell us your new numeric ID". Instead, somebody comes to you and tells you "this is your numeric ID, don't forget it".
So, having that in mind, some advise:
Finally: is is really true: static is an abnormality in good OO design. One should have really good reasons to turn to static fields (except maybe constants) and methods. static always leads to tightly coupled code - and that something to avoid!
Upvotes: 0
Reputation: 2201
Don't use static field as counter of employees. Use instance field instead:
public class Manager {
private int employeesCount;
public Employee addEmployee() {
employeesCount++;
Employee employee = new Employee();
employee.setName("John " + employeesCount);
employee.setLastName("Smith " + employeesCount);
return employee;
}
}
There are lots of good reasons not to use static fields (read: why static variables are bad) to maintain state and one of them is that this makes your code not-testable. If you maintain your state within object (in instance fields), then there is no problem to instantiate your object and just test it as is.
Instead, make sure that there is just one instance of Manager in your program and everyone works with it (this is called singleton). Well, there is singleton pattern. And many good reasons not to use it (read: why singletons are bad). So it ends up with the fact that when you write real app, you typically use some dependency injection framework (like spring or guice) and they have ability to instantiate singleton for you when you want it.
Well, it was a bit of humor here but I'm sure you get idea that global state is considered poor practice and difficulty to test it is one of ways how it manifests itself.
Upvotes: 1