2016-06-22 7 views
4

テストクラスでインスタンス化されたときに@Valueアノテーションがnullを返すサービスで、自動生成コンストラクタを使用しています。依存関係の自動配線は問題を直接解決しますが、プロジェクトはコンストラクターベースの自動配線を使用するという慣例に従います。私の理解では、テストクラスのサービスをインスタンス化することは、@ Valueがnullを返すSpring IoCコンテナからそれを作成していないことです。アプリケーションコンテキストに直接アクセスせずにコンストラクタベースのautowiringを使用してIoCコンテナからサービスを作成する方法はありますか? @Value作業updateServiceはSpringコンテキスト内でなければならないようにするにSpring @Autowiredコンストラクタは、テストクラスでインスタンス化されたとき@Valueがnullを返すようにします。

@RunWith(SpringJUnite4ClassRunner.class) 
@SpringApplicationConfiguration(classes = {TestApplication.class}) 
@WebAppConfiguration 
public class UpdateServiceTest { 

    private UpdateService updateService; 

    @Mock 
    private UserService mockUserService; 

    @Before 
    public void setUp() { 
     MockitoAnnotations.initMocks(this); 

     updateService = new UpdateService(mockUserService); 

    } 
} 
+0

もしあなたが 'UpdateService'ビーンを持っていれば' @ Autowired'だけです。 –

+0

残念ながら、これはテストクラスのmockedオブジェクトでUpdateServiceを構築できる必要があるため、私には役に立ちません。 – Alex

+0

そう、それを逃した。ヒントについてはこちら[こちら](http://stackoverflow.com/questions/2457239/injecting-mockito-mocks-into-a-spring-bean)をご覧ください。 –

答えて

2

例のサービス:

@Component 
public class UpdateService { 

    @Value("${update.success.table}") 
    private String successTable; 

    @Value("${update.failed.table}") 
    private String failedTable; 

    private UserService userService 

    @Autowired 
    public UpdateService(UserService userService) { 
     this.userService = userService; 
    } 
} 

例テストサービス。

... 
public class UpdateServiceTest { 
    @Autowired 
    private UpdateService updateService; 
    ... 

モックUserServiceのprotecteduserServiceを変更し、考慮した

オプション:

Springフレームワークの統合テストのためのベストプラクティスは、アプリケーションのテストでは、テストコンテキストとオートワイヤリング・テスト・ソースのコンテキストを含めることですそのテストクラスとソースクラスは同じパッケージに含まれています。 Whiteboxと反射と

@Before 
public void setUp() { 
    MockitoAnnotations.initMocks(this); 

    updateService.userService = mockUserService; 
} 

オプション:

@Before 
public void setUp() { 
    MockitoAnnotations.initMocks(this); 

    Whitebox.setInternalState(updateService, 'userService', mockUserService); 
} 
+0

残念なことに、直接Autowriing UpdateServiceは私が虚偽のUserServiceオブジェクトでオブジェクトを構築できる必要があるために助けにならない – Alex

+0

@Alexそれはあなたに2つのオプションがあるので、あなたは 'private UserService userService'を保護して、モックインスタンスを割り当てたり、リフレクションを使用してプライベートフィールドを変更したりして、モックを持つBeanを作成します。 – gevorg

+0

私はUserServiceを直接設定する必要がないようにします。 Whiteboxでリフレクションを使用すると、トリックはありましたが、ありがとう! – Alex

1

@Valueばねコンテキストでポスト・プロセッサであるプロパティプレースホルダ構成器によって充填されています。​​はコンテキストの一部ではないため、処理されません。

セットアップは、ユニットと統合テストの不明瞭な混合のように少し見えます。単体テストでは、春の文脈はまったく必要ありません。

public class UpdateServiceTest { 

    @InjectMocks 
    private UpdateService updateService; 

    @Mock 
    private UserService mockUserService; 

    @Before 
    public void setUp() { 
     MockitoAnnotations.initMocks(this); 
     ReflectionTestUtils.setField(updateService, "successTable", "my_success"); 
     updateService.failedTable = "my_failures"; 
    } 
} 

全ての配線がスプリングによって行われるべきで、統合テストの場合:単純に(いずれも図示)で保護し、それらを設定したり、ReflectionTestUtils.setField()を使用@Value注釈付きのメンバーパッケージを作ります。このため

私はモックユーザサービスを提供する内部コンフィグクラスを追加(@Primaryだけで、あなたのコンテキストで任意の他のユーザー・サービスを持っている場合である)とモックがへの簡単なアクセスを持つためにここに静的メンバに格納されますその後のテストからのモック。

@RunWith(SpringJUnite4ClassRunner.class) 
@SpringApplicationConfiguration(classes = {TestApplication.class, UpdateServiceTest.TestAddOn.class}) 
@WebAppConfiguration 
public class UpdateServiceTest { 

    @Autowired 
    private UpdateService updateService; 

    private static UserService mockUserService; 



    static class TestAddOn { 
     @Bean 
     @Primary 
     UserService updateService() { 
     mockUserService = Mockito.mock(UserService.class); 
     return mockUserService; 
     } 
    } 
} 
関連する問題