1. 程式人生 > >junit的test 方法執行兩次

junit的test 方法執行兩次

個人筆記

描述:在當前的junit class定義了一個方法,test,裡面的邏輯是做一個數據庫插入操作

結果:插入操作執行了2次

父類

@RunWith(SpringJUnit4ClassRunner.class)
public abstract class AbstractTest {

	@Before
	public void test() {
		MockitoAnnotations.initMocks(this);
	}
	
}
執行邏輯的junit
@ContextConfiguration(locations = { "classpath*:demo.xml" })
public class DaoTest extends AbstractTest{

	@Resource
	Dao dao;
	
	@Test
	public void test() {
		DaoModel model = new DaoModel();
		model.setUpdateTime(new Date());
		dao.saveObj(model);
	}
}

debug的結果: 由於父類@Before方法和子類的@Test方法重名造成的。

分析:spring構造了org.junit.internal.runners.statements.RunBefores

流程

SpringJUnit4ClassRunner.withBefores ->
BlockJUnit4ClassRunner.withBefores ->
new RunBefores

public RunBefores(Statement next, List<FrameworkMethod> befores, Object target) {
        this.next = next;
        this.befores = befores;
        this.target = target;
}
它的befores就是AbstractTest,next是當前的DaoTest,target是model累

然後繼續執行,

SpringJUnit4ClassRunner.runChild ->

org.junit.runners.model.FrameworkMethod的invokeExplosively方法

public Object invokeExplosively(final Object target, final Object... params)
            throws Throwable {
        return new ReflectiveCallable() {
            @Override
            protected Object runReflectiveCall() throws Throwable {
                return method.invoke(target, params);
            }
        }.run();
}
這時候method是AbstractTest的test方法,target是DaoTest類,則這時執行了一次DaoTest的test方法。

test方法執行完後,在進入RunBefores的evaluate方法,這時候的next是DaoTest,則導致了又執行了一次test方法。

so,更改父類的@Before方法名稱。