Testowanie singletona

0

Tworze zadanie na platforme z roznymi zagadkami programistycznymi (kiedys reklamowalem ten serwis w dziale OT). Wymyslilem sobie, zeby uzytkownicy zaimplementowali bezpiecznego watkowo singletona z leniwa ewaluacja.

Przykladowo zle zaimplementowany przez uzytkownika singleton moze wygladac tak:

	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();}
		return instance;
	}

A moj test jednostkowy weryfikujacy rozwiazanie tak:

public void testUnique() throws ExecutionException, InterruptedException {
		final ExecutorService pool = Executors.newFixedThreadPool(2);
		final Future<Singleton> value1 = pool.submit(() -> Singleton.getInstance());
		final Future<Singleton> value2 = pool.submit(() -> Singleton.getInstance());
		assertEquals(value1.get(), value2.get());
	}

Oczywiscie aby test sie wywalil musi byc powtorzony wiele razy. Idea nie jest najlepsza bo mimo wszystko test jest niedeterministyczny, ale lepszego pomyslu nie mam. Problemem jest jednak odpalenie go n razy. Uzycie junitowego @RunWith(Parameterized.class) nie zda egzaminu, poniewaz kazde odpalenie testu powinno byc w osobnej VM. Inaczej w przypadku gdy pierwsza proba przejdzie pomyslnie, reszta nie ma szans sie wywalic. Normalnie moglbym sobie poradzic przy pomocy parametru fork z ant-junit tudziez innych bibliotek wspomagajacych junita, ale na platformie mam tylko JUnit 4.11.

Jednym pomyslem ktory mam jest zaimplementowanie metody reset wykorzystujac refleksje wykonywanej po @After, ktora bedzie ustawiac pole przechowujaca instancje singletona na nulla. Problem w tym, ze niektorzy uzytkownicy moga miec rozne szalone pomysly na zaimplementowanie testowanego singletona i niekoniecznie taka zmienna w ich kodzie byc musi.

0

Nie zastanawiałem się długo, ale na mój gust nie da się deterministycznie przetestować niedeterministycznego kodu w ogólności :)

Pewnym rozwiązaniem byłoby wymuszenie wstawienia długiego sleepa w konstruktor singletona. Mógłbyś to zrobić tak, że np singleton musi dziedziczyć po jakiejś klasie lub przyjmować jakąś tam funkcję do odpalenia podczas konstruowania obiektu. Załatwiłoby to tę najprostszą implementację leniwego singletona, ale bardziej zaawansowane wadliwe singletony dalej by pewnie przechodziły w 99.9999... % przypadków.

1 użytkowników online, w tym zalogowanych: 0, gości: 1