Home | History | Annotate | Download | only in testing
      1 /*
      2  * Copyright (C) 2010 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.testing;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.fail;
     21 
     22 import com.google.common.annotations.GwtCompatible;
     23 
     24 import junit.framework.TestCase;
     25 
     26 import org.junit.Test;
     27 
     28 /**
     29  * @author Luiz-Otavio "Z" Zorzella
     30  */
     31 @GwtCompatible
     32 public class TearDownStackTest extends TestCase {
     33 
     34   private TearDownStack tearDownStack = new TearDownStack();
     35 
     36   @Test
     37   public void testSingleTearDown() throws Exception {
     38     final TearDownStack stack = buildTearDownStack();
     39 
     40     final SimpleTearDown tearDown = new SimpleTearDown();
     41     stack.addTearDown(tearDown);
     42 
     43     assertEquals(false, tearDown.ran);
     44 
     45     stack.runTearDown();
     46 
     47     assertEquals("tearDown should have run", true, tearDown.ran);
     48   }
     49 
     50   @Test
     51   public void testMultipleTearDownsHappenInOrder() throws Exception {
     52     final TearDownStack stack = buildTearDownStack();
     53 
     54     final SimpleTearDown tearDownOne = new SimpleTearDown();
     55     stack.addTearDown(tearDownOne);
     56 
     57     final Callback callback = new Callback() {
     58       @Override
     59       public void run() {
     60         assertEquals("tearDownTwo should have been run before tearDownOne",
     61           false, tearDownOne.ran);
     62       }
     63     };
     64 
     65     final SimpleTearDown tearDownTwo = new SimpleTearDown(callback);
     66     stack.addTearDown(tearDownTwo);
     67 
     68     assertEquals(false, tearDownOne.ran);
     69     assertEquals(false, tearDownTwo.ran);
     70 
     71     stack.runTearDown();
     72 
     73     assertEquals("tearDownOne should have run", true, tearDownOne.ran);
     74     assertEquals("tearDownTwo should have run", true, tearDownTwo.ran);
     75   }
     76 
     77   @Test
     78   public void testThrowingTearDown() throws Exception {
     79     final TearDownStack stack = buildTearDownStack();
     80 
     81     final ThrowingTearDown tearDownOne = new ThrowingTearDown("one");
     82     stack.addTearDown(tearDownOne);
     83 
     84     final ThrowingTearDown tearDownTwo = new ThrowingTearDown("two");
     85     stack.addTearDown(tearDownTwo);
     86 
     87     assertEquals(false, tearDownOne.ran);
     88     assertEquals(false, tearDownTwo.ran);
     89 
     90     try {
     91       stack.runTearDown();
     92       fail("runTearDown should have thrown an exception");
     93     } catch (ClusterException expected) {
     94       assertEquals("two", expected.getCause().getMessage());
     95     } catch (RuntimeException e) {
     96       throw new RuntimeException(
     97         "A ClusterException should have been thrown, rather than a " + e.getClass().getName(), e);
     98     }
     99 
    100     assertEquals(true, tearDownOne.ran);
    101     assertEquals(true, tearDownTwo.ran);
    102   }
    103 
    104   @Override public final void runBare() throws Throwable {
    105     try {
    106       setUp();
    107       runTest();
    108     } finally {
    109       tearDown();
    110     }
    111   }
    112 
    113   @Override protected void tearDown() {
    114     tearDownStack.runTearDown();
    115   }
    116 
    117   /**
    118    * Builds a {@link TearDownStack} that makes sure it's clear by the end of
    119    * this test.
    120    */
    121   private TearDownStack buildTearDownStack() {
    122     final TearDownStack result = new TearDownStack();
    123     tearDownStack.addTearDown(new TearDown() {
    124 
    125       @Override
    126       public void tearDown() throws Exception {
    127         assertEquals(
    128           "The test should have cleared the stack (say, by virtue of running runTearDown)",
    129           0, result.stack.size());
    130       }
    131     });
    132     return result;
    133   }
    134 
    135   private static final class ThrowingTearDown implements TearDown {
    136 
    137     private final String id;
    138     boolean ran = false;
    139 
    140     ThrowingTearDown(String id) {
    141       this.id = id;
    142     }
    143 
    144     @Override
    145     public void tearDown() throws Exception {
    146       ran = true;
    147       throw new RuntimeException(id);
    148     }
    149   }
    150 
    151   private static final class SimpleTearDown implements TearDown {
    152 
    153     boolean ran = false;
    154     Callback callback = null;
    155 
    156     public SimpleTearDown() {}
    157 
    158     public SimpleTearDown(Callback callback) {
    159       this.callback = callback;
    160     }
    161 
    162     @Override
    163     public void tearDown() throws Exception {
    164       if (callback != null) {
    165         callback.run();
    166       }
    167       ran = true;
    168     }
    169   }
    170 
    171   private interface Callback {
    172     void run();
    173   }
    174 }
    175