RestFuse的研究(四) Junit的Statement的分析

               在RestFuse提供了多种单元测试的方式,这里只是关注常用的三种方式.

其中1.常见的请求一次

       2.请求一次并回调.

       3.多个请求.

在junit4中Statement可以用来执行调用.可以采用类似执行链的封装使用.在RestFuse中封装的Statement有多个,如BasicStatement:执行的普通请求相应.

   HttpTestStatement:处理请求的回调和多个调用.

在Destination中Statement被调用:

源代码如下:

	public Statement apply(Statement base, Description description) {
		Statement result;
		Statement result;
		if (hasAnnotation(description)) {
			this.requestStatement = new HttpTestStatement(base, description,
					this.testObject, this.baseUrl, this.proxyHost,
					this.proxyPort, this.context);
			result = this.requestStatement;
		} else {
			result = base;
		}
		return result;
	}

 

HttpTestStatement实现Statement主要代码封装如下:

public class HttpTestStatement extends Statement {
	static final String HTTP_PROXY_HOST = "http.proxyHost";
	static final String HTTP_PROXY_PORT = "http.proxyPort";
	private final Statement base;
	private final Description description;
	private final Object target;
	private final String baseUrl;
	private final String proxyHost;
	private final int proxyPort;
	private final RequestContext context;

	public HttpTestStatement(Statement base, Description description,
			Object target, String baseUrl, String proxyHost, int proxyPort,
			RequestContext context) {
		this.base = base;
		this.description = description;
		this.target = target;
		this.baseUrl = baseUrl;
		this.proxyHost = proxyHost;
		this.proxyPort = proxyPort;
		this.context = context;
	}

	public void evaluate() throws Throwable {
		setProxyProperties();
		try {
			doEvaluate();
		} finally {
			unsetProxyProperties();
		}
	}

	private void setProxyProperties() {
		if (this.proxyHost != null) {
			System.setProperty("http.proxyHost", this.proxyHost);
			System.setProperty("http.proxyPort", String.valueOf(this.proxyPort));
		}
	}

	private void doEvaluate() throws Throwable {
		Statement delegate = new BasicStatement(this.base, this);
		if (needsCallback())
			delegate = new CallbackStatement(this.base, this, this.description,
					this.target);
		else if (needsPoll()) {
			delegate = new PollStatement(this.base, this, this.description,
					this.target);
		}
		delegate.evaluate();
	}

	private void unsetProxyProperties() {
		Properties properties = System.getProperties();
		properties.remove("http.proxyHost");
		properties.remove("http.proxyPort");
	}

	private boolean needsCallback() {
		Callback callbackAnnotation = (Callback) this.description
				.getAnnotation(Callback.class);
		return (callbackAnnotation != null);
	}

	private boolean needsPoll() {
		Poll pollAnnotation = (Poll) this.description.getAnnotation(Poll.class);
		return (pollAnnotation != null);
	}

	public Response sendRequest() {
		InternalRequest request = buildRequest();
		return callService(request);
	}

	private InternalRequest buildRequest() {
		RequestConfiguration requestConfiguration = new RequestConfiguration(
				this.baseUrl, this.description, this.target);
		return requestConfiguration.createRequest(this.context);
	}

	private Response callService(InternalRequest request) {
		Method requestMethod = ((HttpTest) this.description
				.getAnnotation(HttpTest.class)).method();
		Response result = null;
		if (requestMethod.equals(Method.GET))
			result = request.get();
		else if (requestMethod.equals(Method.POST))
			result = request.post();
		else if (requestMethod.equals(Method.DELETE))
			result = request.delete();
		else if (requestMethod.equals(Method.PUT))
			result = request.put();
		else if (requestMethod.equals(Method.HEAD))
			result = request.head();
		else if (requestMethod.equals(Method.OPTIONS)) {
			result = request.options();
		}
		return result;
	}

	public void tryInjectResponse(Response response) {
		Field[] fields = this.target.getClass().getDeclaredFields();
		for (Field field : fields) {
			Context contextAnnotation = (Context) field
					.getAnnotation(Context.class);
			if ((contextAnnotation != null)
					&& (field.getType() == Response.class))
				injectResponse(field, response);
		}
	}

	private void injectResponse(Field field, Response response) {
		field.setAccessible(true);
		try {
			field.set(this.target, response);
		} catch (Exception exception) {
			throw new IllegalStateException("Could not inject response.",
					exception);
		}
	}
}

 可以看出HttpTestStatement起了关键作用

1.setProxyProperties可以看出请求代理的处理.

2.doEvaluate回调和Poll的实现.

3.sendRequest处理了请求调用的过程

4.injectResponse注入单元测试的功能.

 

HttpTestStatement是怎样被RestFuse调用的呢?

          1.首先在执行单元测试类中定义Destination.

           2.执行单元执行的使用调用Rule.

           3.Rule调用Statement.

           4.Statement执行最后调用测试单元.

 

 

 

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