簡體   English   中英

如何在 SpringBootTest 中向 Autowired testRestTemplate 添加基本身份驗證; 彈簧靴 1.4

[英]How to add basic auth to Autowired testRestTemplate in SpringBootTest; Spring Boot 1.4

我在 Spring Boot 1.4 之前的 OAuth 集成測試如下(更新只是為了不使用已棄用的功能):

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { ApplicationConfiguration.class }, webEnvironment = WebEnvironment.RANDOM_PORT)
public class OAuth2IntegrationTest {

    @Value("${local.server.port}")
    private int port;

    private static final String CLIENT_NAME = "client";
    private static final String CLIENT_PASSWORD = "123456";

    @Test
    public void testOAuthAccessTokenIsReturned() {
        MultiValueMap<String, String> request = new LinkedMultiValueMap<String, String>();
        request.set("username", "user");
        request.set("password", password);
        request.set("grant_type", "password");
        @SuppressWarnings("unchecked")
        Map<String, Object> token = new TestRestTemplate(CLIENT_NAME, CLIENT_PASSWORD)
            .postForObject("http://localhost:" + port + "/oauth/token", request, Map.class);
        assertNotNull("Wrong response: " + token, token.get("access_token"));
    }
}

我現在想使用此處所述的 Autowired TestRestTemplate http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-應用程序使用隨機端口

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
    ApplicationConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class OAuth2IntegrationTest {

    private static final String CLIENT_NAME = "client";
    private static final String CLIENT_PASSWORD = "123456";

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    public void testOAuthAccessTokenIsReturned() {
        MultiValueMap<String, String> request = new LinkedMultiValueMap<String, String>();
        request.set("username", "user");
        request.set("password", password);
        request.set("grant_type", "password");
        @SuppressWarnings("unchecked")

        Map<String, Object> token1 = this.testRestTemplate. //how to add basic auth here
        assertNotNull("Wrong response: " + token, token.get("access_token"));
    }
}

我認為這是添加身份驗證的最接近方法:

Spring 4.0.0 使用 RestTemplate 進行基本身份驗證

我想使用 Autowired testRestTemplate 來避免在我的測試中解析主機和端口。 有沒有辦法做到這一點?

這在 Spring Boot 1.4.1 中得到了修復,它有一個額外的方法

testRestTemplate.withBasicAuth(USERNAME,PASSWORD)

@Autowired
private TestRestTemplate testRestTemplate;

@Test
public void testOAuthAccessTokenIsReturned() {
    MultiValueMap<String, String> request = new LinkedMultiValueMap<String, String>();
    request.set("username", USERNAME);
    request.set("password", password);
    request.set("grant_type", "password");
    @SuppressWarnings("unchecked")
    Map<String, Object> token = this.testRestTemplate.withBasicAuth(CLIENT_NAME, CLIENT_PASSWORD)
            .postForObject(SyntheticsConstants.OAUTH_ENDPOINT, request, Map.class);
    assertNotNull("Wrong response: " + token, token.get("access_token"));
}

有一個更好的解決方案,因此您無需每次都重新鍵入 withBasicAuth 部分

@Autowired
private TestRestTemplate testRestTemplate;

@BeforeClass
public void setup() {
    BasicAuthorizationInterceptor bai = new BasicAuthorizationInterceptor(CLIENT_NAME, CLIENT_PASSWORD);
    testRestTemplate.getRestTemplate().getInterceptors().add(bai);
}

@Test
public void testOAuthAccessTokenIsReturned() {
    MultiValueMap<String, String> request = new LinkedMultiValueMap<String, String>();
    request.set("username", USERNAME);
    request.set("password", password);
    request.set("grant_type", "password");
    @SuppressWarnings("unchecked")
    Map<String, Object> token = this.testRestTemplate.postForObject(SyntheticsConstants.OAUTH_ENDPOINT, request, Map.class);
    assertNotNull("Wrong response: " + token, token.get("access_token"));
}

盡管接受的答案是正確的,但在我的情況下,我必須在每個測試方法和類中復制testRestTemplate.withBasicAuth(...)

因此,我嘗試在src/test/java/my.microservice.package定義src/test/java/my.microservice.package的配置:

@Configuration
@Profile("test")
public class MyMicroserviceConfigurationForTest {

    @Bean
    public TestRestTemplate testRestTemplate(TestRestTemplate testRestTemplate, SecurityProperties securityProperties) {
        return testRestTemplate.withBasicAuth(securityProperties.getUser().getName(), securityProperties.getUser().getPassword());
    }

}

似乎具有覆蓋默認TestRestTemplate定義的效果,允許在我的測試類中的任何位置注入憑據感知TestRestTemplate

我不完全確定這是否真的是一個有效的解決方案,但您可以嘗試一下...

我認為如果您仍在應用程序中使用基本身份驗證,並且在 application.properties 文件中設置了“user.name”和“user.password”屬性,則有更好的解決方案:

public class YourEndpointClassTest {
    private static final Logger logger = LoggerFactory.getLogger(YourEndpointClassTest.class);  

    private static final String BASE_URL = "/your/base/url";

    @TestConfiguration
    static class TestRestTemplateAuthenticationConfiguration {

        @Value("${spring.security.user.name}")
        private String userName;

        @Value("${spring.security.user.password}")
        private String password;

        @Bean
        public RestTemplateBuilder restTemplateBuilder() {
            return new RestTemplateBuilder().basicAuthentication(userName, password);
        }
    }


    @Autowired
    private TestRestTemplate restTemplate;

//here add your tests...

在單個測試用例中,您可以這樣做:

@Test
public void test() {
    ResponseEntity<String> entity = testRestTemplate
            .withBasicAuth("username", "password")
            .postForEntity(xxxx,String.class);
    Assert.assertNotNull(entity.getBody());
}

並為每個測試用例在您的測試類中添加此方法:

@Before
public void before() {
    // because .withBasicAuth() creates a new TestRestTemplate with the same 
    // configuration as the autowired one.
     testRestTemplate = testRestTemplate.withBasicAuth("username", "password");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM