Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Unit or Integretation Test have getters and setters?

I am trying to write integration tests and want to make it in a best way regarding programming best practices, etiquette, etc.

First I had a question on how to reuse existing tests in another test class and I found the answer in topic How to reuse existing JUnit tests in another test class?

After moving the base test functionality and relevant member fields into the base class I found out that I need to make the member fields protected or I need to have their appropriate getters and setters in order I could use them in inherited test classes. Here is an example:

public abstract class BaseTests {

    private Class classObj;      // or protected without getter/setter?

    protected void somethingHelper() {
        // Test something
    }

    protected void somethingElseHelper() {
        // Test something for classObj
    }

    public Class getClassObj() {
        return classObj;
    }

    public void setClassObj(Class other) {
        classObj = other;
    }
}

public class TestClass1 extends BaseTests {
    @Test
    public void testSomething() {
        somethingHelper();
    }
}

public class TestClass2 extends BaseTests {
    @Test
    public void testSomethingAndSomethingElse() {
        somethingHelper();

        ClassObj obj = new ClassObj();
        // set obj member fields
        // and then test something else
        setClassObj(obj);   // or classObj = obj;?
        somethingElseHelper();
    }
}

My questions are:

  • Is it a good practice to have member fields in base test class and use them in inherited test classes?
  • If yes, what is better: protected member fields or getters/setters?
  • If no, is there another way to achieve what I wanted in example?
like image 606
Armine Avatar asked Feb 06 '23 20:02

Armine


2 Answers

It is not necessarily bad practice to have getters, as long as you keep in mind that unit testing is about isolating behavior and testing specific units of work. Following that, you should make sure that your getters are always returning new instances of objects, instead of dishing out the same copy to all of your unit testing methods.

Sharing objects can cause a lot of issues in unit tests. Most test runners execute tests in parallel, and don't guarantee order execution. Your tests will most likely be modifying the objects, so sharing objects can break other tests in unpredictable ways.

I often create small factory methods for creating objects that I use in all my tests. Especially for the specific class that is being tested.

public ClassUnderTest GetNewClassUnderTest()
{
    return new ClassUnderTest("My favorite string", 1234);
}

As far as breaking test functionality into helper methods, I prefer not to do that. It makes test code difficult to scan over quickly. If it is something simple like one or two lines of code, I always include it inline in my tests. Anything more than that and I start to think about refactoring my tests into something more simple, if possible.

EDIT: I would also highly recommend reading The Art of Unit Testing. It's a great book that has a lot of great advice for building and structuring your unit tests.

like image 96
Danny Avatar answered Feb 20 '23 11:02

Danny


Jay Fields ( se-radio podcast ) points out there are somehow different rules when writing unit tests.

Of course you should still try to avoid code duplication. But the primary thing that determines whether a unit test is helpful ... is the amount of time that you need in order to understand a failing test.

In other words: ideally, any test method within your test classes or suites are independent of each other. You just read that one method; and you understand what it is doing; you look at the failure; and you found all you need.

Compare that to a solution where (complicated) coupling exists; for example because your concrete test method relies on a lot of things that come even from outside of that class; for example via inheritance.

But as others have said: this very much depends on you and your team. You need a lot of experience in order to create really helpful tests; and there are no simply rules that guarantee great results when blindly following them.

like image 28
GhostCat Avatar answered Feb 20 '23 10:02

GhostCat