使用多種MIME類型測試REST API

REST,Spring,Testing
Remote
1
08:52 PM · Dec 01 ,2025

1. 概述

本文將重點介紹如何測試具有多種媒體類型/表示形式的 REST 服務。

我們將編寫能夠在多種表示形式之間切換的集成測試,這些表示形式由 API 支持。目標是能夠運行相同的測試,消耗相同的 URI,但請求不同的媒體類型。

2. 目標

任何 REST API 都需要通過使用一種或多種媒體類型來暴露其資源表示形式。 客户端將通過設置 Accept 標頭來選擇它從服務中請求的表示形式。

由於資源可以有多種表示形式,因此服務器必須實現一個負責選擇正確表示形式的機制。 這也稱為內容協商。

因此,如果客户端請求 application/xml,則應收到資源的 XML 表示形式。 如果它請求 application/json,則應收到 JSON。

3. 測試基礎設施

我們將首先定義一個簡單的接口,用於一個marshaller。這將是主要的抽象,允許測試在不同的Media Type之間切換:

public interface IMarshaller {
    ...
    String getMime();
}

然後我們需要一種方法來根據某種外部配置初始化正確的marshaller。

為此,我們將使用Spring的FactoryBean來初始化marshaller,以及一個簡單的屬性來確定要使用的marshaller:

@Component
@Profile("test")
public class TestMarshallerFactory implements FactoryBean<IMarshaller> {

    @Autowired
    private Environment env;

    public IMarshaller getObject() {
        String testMime = env.getProperty("test.mime");
        if (testMime != null) {
            switch (testMime) {
            case "json":
                return new JacksonMarshaller();
            case "xml":
                return new XStreamMarshaller();
            default:
                throw new IllegalStateException();
            }
        }

        return new JacksonMarshaller();
    }

    public Class<IMarshaller> getObjectType() {
        return IMarshaller.class;
    }

    public boolean isSingleton() {
        return true;
    }
}

讓我們看看這個:

  • 首先,這裏使用了Spring 3.1中引入的新抽象Environment——關於如何使用Properties與Spring,請查看詳細的文章
  • 我們從環境中檢索test.mime屬性,並使用它來確定要創建的marshaller——這裏使用了Java 7的switch on String語法
  • 接下來,如果屬性未定義,則默認marshaller將是用於JSON支持的Jacksonmarshaller
  • 最後——這個BeanFactory僅在測試場景中處於活動狀態,因為我們使用了@Profile支持,該支持也引入於Spring 3.1

這就是它——該機制能夠根據test.mime屬性的值在marshaller之間切換。

4. JSON 和 XML 轉換器

接下來,我們需要實際的轉換器實現——針對每種支持的媒體類型一個。

對於 JSON,我們將使用 Jackson 作為底層庫:

public class JacksonMarshaller implements IMarshaller {
    private ObjectMapper objectMapper;

    public JacksonMarshaller() {
        super();
        objectMapper = new ObjectMapper();
    }

    ...

    @Override
    public String getMime() {
        return MediaType.APPLICATION_JSON.toString();
    }
}

對於 XML 支持,轉換器使用 XStream

public class XStreamMarshaller implements IMarshaller {
    private XStream xstream;

    public XStreamMarshaller() {
        super();
        xstream = new XStream();
    }

    ...

    public String getMime() {
        return MediaType.APPLICATION_XML.toString();
    }
}

請注意,這些轉換器本身不是 Spring Bean。 原因是它們將在 TestMarshallerFactory 中進行啓動,因此無需直接將其聲明為組件。

5. 使用 JSON 和 XML 消費服務

到目前為止,我們應該能夠對部署的服務運行完整的集成測試。使用marshaller非常簡單:我們將IMarshaller注入到測試中:

@ActiveProfiles({ "test" })
public abstract class SomeRestLiveTest {

    @Autowired
    private IMarshaller marshaller;

    // tests
    ...

}

Spring 將根據 test.mime 屬性的值來確定要注入的確切marshaller。

如果未為該屬性提供值,TestMarshallerFactory 將簡單地回退到默認marshaller——JSONmarshaller。

6. Maven 和 Jenkins

如果 Maven 設置為在已部署的 REST 服務上運行集成測試,則可以使用以下命令:

mvn test -Dtest.mime=xml

或者,如果構建使用 Maven 生命週期中的 integration-test 階段:

mvn integration-test -Dtest.mime=xml

有關如何設置 Maven 構建以運行集成測試的更多詳細信息,請參閲 與 Maven 進行集成測試 文章。

通過 Jenkins,必須使用以下配置:

此構建已參數化

以及添加的 字符串參數test.mime=xml

一種常見的 Jenkins 配置是讓多個工作項運行相同的集成測試套件,這些測試套件針對已部署的服務,一個使用 XML,另一個使用 JSON 表示。

7. 結論

本文介紹瞭如何測試能夠同時支持多種表示形式的 REST API。 大多數 API 會發布其資源在多種表示形式下,因此測試所有這些表示形式至關重要。 能夠使用相同的測試在所有這些表示形式下,這真是太酷了。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.