Home > Java Puzzle > Racy Little Number

Racy Little Number

Na dziś przygotowałem zagadkę skierowaną przede wszystkim dla tych, którzy piszą testy do swojego kodu. Praktykujesz TDD, BDD lub używasz innej techniki – na pewno poradzisz sobie z zagadką.

  • Jak często poniższy test się powiedzie?
import junit.framework.TestCase;

public class Test extends TestCase {

  int number;

  public void test() throws InterruptedException {
    number = 0;
    Thread t = new Thread(new Runnable() {
      public void run() {
        assertEquals(2, number);
      }
    });

    number = 1;
    t.start();
    number++;
    t.join();
  }
}


Odpowiedzi:
(a) Zawsze się nie powodzi
(b) Czasami się powodzi
(c) Zawsze się powodzi
(d) Zawsze się zawiesza

  • Odpowiedź uzasadnij i wyjaśnij dlaczego tak to działa
  • Jak poprawić powyższy kod, aby zachowywał się zgodnie z intuicją

Autorami zagadki są Joshua Bloch i William Pugh

  1. 14 marca, 2011 at 20:28 | #1

    Odpowiedź: test zawsze się powiedzie
    Uzasadnienie: wyjątek rzucany przez asercję w ciele wątku roboczego nie zostanie nigdzie przekazany. Wątek roboczy po rzuceniu wyjątku przez asercję po prostu się zakończy nie przekazując żadnej informacji do kontenera testów.

    Wersja poprawiona:

    import junit.framework.TestCase;
    
    
    public class Test extends TestCase {
    	
    	Error err;
    	
    	Exception e;
    	
    	int number;
    
    	public void setUp() {
    		err = null;
    		e = null;
    	}
    
    	public void test() throws InterruptedException {
    		
    		number = 0;
    		Thread t = new Thread(new Runnable() {
    			public void run() {
    				try {
    					assertEquals(2, number);
    				} catch (Error e1) {
    					err = e1;
    				} catch (Exception e1) {
    					e = e1;
    				}
    			}
    		});
    		
    		number = 1;
    		t.start();
    		number++;
    		t.join();
    	}
    
    	public void tearDown() throws Exception {
    		
    		if (err != null) {
    			throw err;
    		}
    		
    		if (e != null) {
    			throw e;
    		}
    	}
    }
    
  1. Brak jeszcze trackbacków