2017-01-21 6 views
2

テストプロパティファイルを使用でき、いくつかのプロパティをオーバーライドできるようにしたい。すべての単一のプロパティをオーバーライドすることは醜い高速になります。Spring環境で選択されたプロパティのみを模擬する

  • @Autowired private Environment env;
    • この

      は私が

      @RunWith(SpringRunner.class) 
      @SpringBootTest(classes = MyApp.class) 
      @TestPropertySource(
           locations = { "classpath:myapp-test.properties" }, 
           properties = { "test.key = testValue" }) 
      public class EnvironmentMockedPropertiesTest { 
      
          @Autowired private Environment env; 
          // @MockBean private Environment env; 
      
          @Test public void testExistingProperty() { 
           // some.property=someValue 
           final String keyActual = "some.property"; 
           final String expected = "someValue"; 
           final String actual = env.getProperty(keyActual); 
           assertEquals(expected, actual); 
          } 
      
          @Test public void testMockedProperty() { 
           final String keyMocked = "mocked.test.key"; 
           final String expected = "mockedTestValue"; 
           when(env.getProperty(keyMocked)).thenReturn(expected); 
           final String actual = env.getProperty(keyMocked); 
           assertEquals(expected, actual); 
          } 
      
          @Test public void testOverriddenProperty() { 
           final String expected = "testValue"; 
           final String actual = env.getProperty("test.key"); 
           assertEquals(expected, actual); 
          } 
      
      } 
      

      私は何を見つけることである性質を模擬し、テストケース内の既存のプロパティを使用するために自分の能力をテストするために使用していたコードですtestExistingProperty()およびtestOverriddenProperty()は、パス

    • testMockedProperty()
  • @MockBean private Environment env;
    • testMockedProperty()失敗
    • testExistingProperty()testOverriddenProperty()は私が目指しています何を達成するための方法はあり

に失敗渡しますか?

依存性:

<spring.boot.version>1.4.3.RELEASE</spring.boot.version> 
... 
<!-- Spring --> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot</artifactId> 
    <version>${spring.boot.version}</version> 
</dependency> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-autoconfigure</artifactId> 
    <version>${spring.boot.version}</version> 
</dependency> 
<!-- Starter for testing Spring Boot applications with libraries including JUnit, 
    Hamcrest and Mockito --> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-test</artifactId> 
    <version>${spring.boot.version}</version> 
</dependency> 
+0

これを実現するには、モックされたデータと実際のデータの両方を処理する能力を持つ環境変数envを1つだけ使用したいと思っていますか? –

答えて

1

私はこの作品を作ってきた[OK]を、あなたが探しているものaccompishするMockitoを使用する必要があります。

Mavenの依存関係

<dependency> 
    <groupId>org.mockito</groupId> 
    <artifactId>mockito-core</artifactId> 
    <version>2.6.4</version> 
</dependency> 

テストクラス設定

import static org.mockito.Mockito.*; 
import static org.springframework.test.util.AopTestUtils.getTargetObject; 

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = MyApp.class) 
@TestPropertySource(
     locations = { "classpath:myapp-test.properties" }, 
     properties = { "test.key = testValue" }) 

public class AnswerTest { 

    // This will be only for injecting, we will not be using this object in tests. 
    @Autowired 
    private Environment env; 

    // This is the reference that will be used in tests. 
    private Environment envSpied; 

    // Map of properties that you intend to mock 
    private Map<String, String> mockedProperties; 

    @PostConstruct 
    public void postConstruct(){ 
     mockedProperties = new HashMap<String, String>(); 
     mockedProperties.put("mocked.test.key_1", "mocked.test.value_1"); 
     mockedProperties.put("mocked.test.key_2", "mocked.test.value_2"); 
     mockedProperties.put("mocked.test.key_3", "mocked.test.value_3"); 

     // We use the Spy feature of mockito which enabled partial mocking 
     envSpied = Mockito.spy((Environment) getTargetObject(env)); 

     // We mock certain retrieval of certain properties 
     // based on the logic contained in the implementation of Answer class 
     doAnswer(new CustomAnswer()).when(envSpied).getProperty(Mockito.anyString()); 
    } 

テストケース

// Testing for both mocked and real properties in same test method 
    @Test public void shouldReturnAdequateProperty() { 
     String mockedValue = envSpied.getProperty("mocked.test.key_3"); 
     String realValue = envSpied.getProperty("test.key"); 

     assertEquals(mockedValue, "mocked.test.value_3"); 
     assertEquals(realValue, "testValue"); 
    } 

Mockitoの回答インターフェイスの実装

// Here we define what should mockito do: 
    // a) return mocked property if the key is a mock 
    // b) invoke real method on Environment otherwise 
    private class CustomAnswer implements Answer<String>{ 

     @Override 
     public String answer(InvocationOnMock invocationOnMock) throws Throwable { 
      Object[] arguments = invocationOnMock.getArguments(); 
      String parameterKey = (String) arguments[0]; 

      String mockedValue = mockedProperties.get(parameterKey); 

      if(mockedValue != null){ 
       return mockedValue; 
      } 

      return (String) invocationOnMock.callRealMethod(); 
     } 
    } 
} 

それを試してみてください、そして、すべてがここに明確であるなら、私に知らせてください。

+0

'getTargetObject()はどこから来ますか? –

+1

申し訳ありませんが輸入を忘れてしまった。私は投稿を更新しました –

+0

これはかなり複雑ですが、うまくいきますので、どうもありがとうございます。 :)私は '@ MockBeanは単に私が望んでいたことをしていない、それは恥です:私は嘲笑の考えは、あなたが実際に必要なもの(またはスパイ? –

関連する問題