Clearing static state before each method

My SUT class depends on external static state (which generally should be avoided, I know). How do I make sure my tests do not depend on their order of execution? I mean other by introducing some reset()/clear() method that is invoked @BeforeEach test. I'm not 100% comfortable introducing changes in business code solely for testing (the business logic does not require such a method, at least not yet). /* This is the essence of it: MyClass is one of Cache's clients: if it can get a cached MyData instance, it doesn't use its dao */ @Test void doSomething_ifDataCached_noDbCalls() { Cache.cache(something); MyDao dao = mock(); MyClass myClass = new MyClass(daoMock); myClass.doSomething(); then(daoMock).shouldHaveNoInteractions(); } @Test void doSomething_ifDataNotCached_noDbCalls() { MyData data = new MyData("some expensive data"); MyDao dao = mock(); given(dao.findData()).willReturn(Arrays.asList(data)); MyClass myClass = new MyClass(daoMock); myClass.doSomething(); then(daoMock).should().findData(); // fails given this test order: MyData's still in cache } // works but a bit questionable @BeforeEach void setUp() { Cache.clear(); } It's not a "how do I do X" question. Rather, it's about how I can ensure a solid test design. JUnit 5, Mockito, Java 8.

Feb 7, 2025 - 12:42
 0
Clearing static state before each method

My SUT class depends on external static state (which generally should be avoided, I know).

How do I make sure my tests do not depend on their order of execution?

I mean other by introducing some reset()/clear() method that is invoked @BeforeEach test. I'm not 100% comfortable introducing changes in business code solely for testing (the business logic does not require such a method, at least not yet).

    /* This is the essence of it:
       MyClass is one of Cache's clients: if it can get 
       a cached MyData instance, it doesn't use its dao */
    @Test
    void doSomething_ifDataCached_noDbCalls() {
        Cache.cache(something);

        MyDao dao = mock();
        MyClass myClass = new MyClass(daoMock);

        myClass.doSomething();

        then(daoMock).shouldHaveNoInteractions();
    }

    @Test
    void doSomething_ifDataNotCached_noDbCalls() {
        MyData data = new MyData("some expensive data");
        MyDao dao = mock();

        given(dao.findData()).willReturn(Arrays.asList(data));
        MyClass myClass = new MyClass(daoMock);

        myClass.doSomething();

        then(daoMock).should().findData(); // fails given this test order: MyData's still in cache
    }
// works but a bit questionable
    @BeforeEach
    void setUp() {
        Cache.clear();
    }

It's not a "how do I do X" question. Rather, it's about how I can ensure a solid test design.

JUnit 5, Mockito, Java 8.