spock test没有正确设置返回值

时间:2014-07-16 19:46:05

标签: java unit-testing groovy spock

所以我试图测试以下方法在statusCode为401时抛出异常:

HttpEntity doGet(HttpGet httpGet) {
    # other stuff...
    HttpResponse response = this.httpClient.execute(httpGet); // LINE 3
    int statusCode = response.getStatusLine().getStatusCode(); // LINE 4
    if (statusCode == 401) {
        throw new ApiClientException(401, "Recheck your login username & password credentials in the " +
                            "file Configurations.groovy as they are NOT working.");
    }
    # other stuff...
}

我正在使用Spock测试框架,您可以使用">>"指定方法对对象的返回值。因此,当调用代码response.getStatusLine().getStatusCode()时,我想控制它在上面的第4行返回401。

我试图在第18行& 19在以下测试中,但它不起作用:

def "test doGet(HttpGet httpGet) throws the correct exceptions when given unsuccessful HttpGet instance"() {
        given:
        def httpGet = new HttpGet("http://sand.api.appnexus.com/member?id=1196");

        def httpClient = Stub(HttpClient);
        this.apiClient.httpClient = httpClient;

        def httpResponseWithStatusCode401 = Stub(HttpResponse);

        httpClient.execute(httpGet) >> httpResponseWithStatusCode401; # LINE 18 This response is correctly returning

        httpResponseWithStatusCode401.getStatusLine().getStatusCode() >> 401; # LINE 19 this is never returning 401 right now and always 0 instead

        when:
        ApiClientException expectedException;
        try {
            this.apiClient.doGet(httpGet);
        } catch(ApiClientException expected) {
            expectedException = expected;
        }

        then:    
        expectedException.getMessage().equals("Recheck your login username & password credentials in the " +
                "file Configurations.groovy as they are NOT working.");
    }

问题:如何让LINE 4在LINES 19的测试中返回我想要的内容?

1 个答案:

答案 0 :(得分:3)

这是你应该如何实施这个测试:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')
@Grab('org.apache.httpcomponents:httpclient:4.3.4')

import spock.lang.*
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.HttpClient
import org.apache.http.HttpEntity
import org.apache.http.HttpResponse
import org.apache.http.StatusLine
import org.apache.http.message.BasicHttpResponse

class Test extends Specification {

    def "test doGet(HttpGet httpGet) throws the correct exceptions when given unsuccessful HttpGet instance"() {
        given:
        def client = new Client()
        client.httpClient = GroovyMock(HttpClient) {
            execute(_) >> new BasicHttpResponse(null, 401, '')
        }

        when:
        client.doGet(GroovyMock(HttpGet))

        then:
        def e = thrown(ApiClientException)
        e.code == 401
        e.message == 'Recheck your login username & password credentials in the file Configurations.groovy as they are NOT working.'
    }
}

class ApiClientException extends Exception {

    def code
    def msg

    ApiClientException(code, msg) {
        this.code = code
        this.msg = msg
    }

    String getMessage() {
        'Recheck your login username & password credentials in the file Configurations.groovy as they are NOT working.'
    }
}

class Client {

    def HttpClient httpClient

    HttpEntity doGet(HttpGet httpGet) {

        HttpResponse response = httpClient.execute(httpGet)
        int statusCode = response.getStatusLine().getStatusCode()
        if (statusCode == 401) {
            throw new ApiClientException(401, "Recheck your login username & password credentials in the " +
                    "file Configurations.groovy as they are NOT working.");
        }
    }
}

这一切都清楚了吗?