RestFuse的研究(三) Junit的Rule的使用和分析

          在junit中定义一些可以公用的规则(Rule),类似拦截器和拦截器链的概念.在Junit4版本中针对不同的版本Rule的接口不一样,在Junit4.11和Junit4.10 采用实现TestRule接口.在Junit4.8采用的MethodRule接口.

备注:

         RestFuse使用1.2.0,

          Junit采用4.10版本.

如在RestFuse中定义Destination实现TestRule接口.实现apply方法:

public Statement apply(Statement base, Description description);

 

使用如下:

package com.easyway.restfuse;

import org.junit.Rule;
import org.junit.runner.RunWith;

import com.eclipsesource.restfuse.Destination;
import com.eclipsesource.restfuse.HttpJUnitRunner;
import com.eclipsesource.restfuse.Method;
import com.eclipsesource.restfuse.Response;
import com.eclipsesource.restfuse.annotation.Context;
import com.eclipsesource.restfuse.annotation.HttpTest;
/**
 * 
 * @author longgangbai
 *
 */
@RunWith( HttpJUnitRunner.class )
public class RestfuseTest {
 
  @Rule
  public Destination destination = new Destination("", "http://restfuse.com" ); 
 
  @Context
  private Response response; // will be injected after every request
 
  @HttpTest( method = Method.GET, path = "/" )
  public void checkRestfuseOnlineStatus() {
	  System.out.println( response);
  }  
}

 

在junit4中Rule怎么调用的呢?

     在BlockJUnit4ClassRunner中的methodBlock中进行测试方法的各种操作.如BeforeMethod,AfterMethod等的组装为Statement .

	protected Statement methodBlock(FrameworkMethod method) {
		Object test;
		try {
			test = new ReflectiveCallable() {
				protected Object runReflectiveCall() throws Throwable {
					return BlockJUnit4ClassRunner.this.createTest();
				}
			}.run();
		} catch (Throwable e) {
			return new Fail(e);
		}

		Statement statement = methodInvoker(method, test);
		statement = possiblyExpectingExceptions(method, test, statement);
		statement = withPotentialTimeout(method, test, statement);
		statement = withBefores(method, test, statement);
		statement = withAfters(method, test, statement);
		statement = withRules(method, test, statement);
		return statement;
	}

 其中最后一个withRules,同时可以看出possiblyExpectingExceptions,withPotentialTimeout,withBefores,withAfters被不推荐使用.其实他们几个都可以采用Rule的方式现实,这也是不推荐使用的主要原因.

 

具体的Rule相关的源代码:

	private Statement withRules(FrameworkMethod method, Object target,
			Statement statement) {
		List testRules = getTestRules(target);
		Statement result = statement;
		result = withMethodRules(method, testRules, target, result);
		result = withTestRules(method, testRules, result);

		return result;
	}

	private Statement withMethodRules(FrameworkMethod method,
			List<TestRule> testRules, Object target, Statement result) {
		for (MethodRule each : getMethodRules(target)) {
			if (!(testRules.contains(each))) {
				result = each.apply(result, method, target);
			}
		}
		return result;
	}

	private List<MethodRule> getMethodRules(Object target) {
		return rules(target);
	}

	protected List<MethodRule> rules(Object target) {
		return getTestClass().getAnnotatedFieldValues(target, Rule.class,
				MethodRule.class);
	}

	private Statement withTestRules(FrameworkMethod method,
			List<TestRule> testRules, Statement statement) {
		return new RunRules(statement, testRules, describeChild(method));
	}

	protected List<TestRule> getTestRules(Object target) {
		List result = getTestClass().getAnnotatedMethodValues(target,
				Rule.class, TestRule.class);

		result.addAll(getTestClass().getAnnotatedFieldValues(target,
				Rule.class, TestRule.class));

		return result;
	}

 

可以看出Rule不仅有类级别的还有方法的级别的.

 

 

你可能感兴趣的:(JUnit4,Rule,Runner,RestFuse)