SpringBootおよびSpringCloudConfigサービスを使用して構成値を提供するサービスを実装しています。私のサービスには、リモートGitリポジトリで値が変更されたときに更新する必要があるいくつかの構成値があり@RefreshScope
、その機能を有効にするために使用していました。
RestTemplate
そのサービスにモックを挿入しようとすると問題が発生します。モックを無視して、代わりに自動配線されたインスタンスを使用しているように見えます。注釈をコメントアウトすると、正常に機能しているようです。
サービスのコードは次のとおりです。
@Service
@RefreshScope
public class MyServiceImpl implements MyService {
private static final Logger LOG = Logger.getLogger(MyServiceImpl.class);
@Autowired
public RestTemplate restTemplate;
@Value("${opts.default}")
private String default;
@Value("${opts.address}")
private String address;
@Value("${opts.separator}")
private String separator;
...
}
テストソースコード:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ServiceTest {
@Mock
private RestTemplate restTemplate;
@Autowired
@InjectMocks
private MyServiceImpl service;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
public void testMethod() throws Exception {
when(restTemplate.postForObject(anyString(), any(), eq(ServiceResponse.class), anyMap())).thenReturn(getSuccessfulResponse());
ServiceResponse response = service.doYourStuff();
Assert.assertNotNull(response);
Assert.assertTrue(response.isSuccessful());
}
...
}
@RefreshScope
Beanを追加すると、実際の生の実装ではなくプロキシになります。現在、RestTemplate
は基になるインスタンスではなくプロキシに設定されています。(デバッグすると、MyServiceImpl
実際にはのインスタンスに似ていることがわかりますMyServiceImpl$SpringCgLib#353234
)。
修正するには、ReflectionTestUtils
とを使用して依存関係を手動で設定する必要がありAopTestUtils
ます。後者は、実際のプロキシを取得することです。
モックの初期化後に@InjectMocks
アノテーションを削除し、setup
メソッドに以下を追加します。
Object actualTarget = AopTestUtils.getUltimateTargetObject(service);
ReflectionTestUtils.setfield(actualTarget, "restTemplate", restTemplate);
4.2より前のバージョンの場合、次の方法でうまくいく可能性があります
Object actualTarget = (service instanceof Advised) ? ((Advised) service).getTargetSource().getTarget() : service;
問題は、Mockitoがプロキシを検出せず、フィールドを設定するだけであるということです。ReflectionTestUtils
プロキシのいずれかので、手動アンラップを検出しません。私は実際に数回前にこのトラップに足を踏み入れたので、今朝SPR-14050を作成してReflectionTestUtils
、痛みを少し和らげるためにそれを埋め込むことにしました。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加