2017-03-29 162 views
1

我想在我的測試中嘲笑一個調用,但我得到一個錯誤,因爲它調用真正的方法比嘲笑它。嘲笑不能模擬方法調用

這是我的方法

@Value("${omega.aws.nonprod-profile}") 
private String nonProdProfile; 

@Autowired 
AwsService awsService; 

public List<SecurityGroup> getAllSecurityGroups() {   
    AmazonEC2 ec2 = configSetter();  
    return awsService.getAllSecurityGroups(ec2); 
} 

protected AmazonEC2 configSetter() { 

    ProfileCredentialsProvider credentials = new ProfileCredentialsProvider(nonProdProfile); 
    ClientConfiguration clientCfg = new ClientConfiguration(); 
    clientCfg.setProxyHost(this.proxyHost); 
    clientCfg.setProxyPort(Integer.valueOf(proxyPort)); 
    clientCfg.setProtocol(Protocol.HTTPS); 
    return new AmazonEC2Client(credentials, clientCfg);  

}

這裏是我的測試類

@InjectMocks 
    private AwsConfigurationLocal subject; 

    @Mock 
    private AwsService awsService; 

    @Test 
    public void TestgetAllSecurityGroups() throws Exception { 

     ec2 = Mockito.mock(AmazonEC2Client.class); 
     securityGroup = new SecurityGroup(); 
     List<SecurityGroup> result = Collections.singletonList(securityGroup); 
     Mockito.when(awsService.getAllSecurityGroups(ec2)).thenReturn(result); 
     List<SecurityGroup> actual = subject.getAllSecurityGroups(); 
     assertThat(actual, CoreMatchers.is(equals(result))); 
    } 

測試實際調用保護方法configSetter和設置代理時失敗。幫助我瞭解我在這裏做錯了什麼。

+0

嘲笑的情況下,你能提供與頂級級別的註解完整的測試類的代碼? – developer

+0

@javaguy你的意思是在我的主題類中自動裝配AwsService? – amulamul

+2

您的測試期望awsService.getAllSecurityGroups()以yoyr模擬的ec2作爲參數來調用。但是你的代碼不會用你的模擬ec2來調用它。它通過調用configSetter()創建的ec2來調用它() –

回答

0

subject.getAllSecurityGroups();調用真正configSetter()返回這又是上awsService.getAllSecurityGroups(ec2);通過實際AmazonEC2。該參數與您的模擬ec2不匹配,所以默認的模擬實現返回(我想它爲空)爲actual

所以問題是:沒有什麼能阻止configSetter()被調用的真正實現。 如果註釋subject@Spy

Mockito.when(subject.configSetter()).then(ec2); 

它應該工作正常。

這就是說有很多設置只是爲了檢查被委派的簡單調用。這是由於AwsConfigurationLocal中兩個責任的混合 - 創建AmazonEC2Client並提供getAllSecurityGroups()。如果你把前者分成單獨的班級(比如說AmazonEC2ClientFactor),一切都應該落實到位。

+0

使用@spy註釋並嘲諷'Mockito.when(subject.configSetter())。then(ec2);'具有相同的結果。它呼籲真正的方法。該類用於創建AmazonEC2Client,getAllSecurityGroup將調用委託給另一個類。我有這個方法configSetter作爲這個類中的常用方法。 – amulamul

0

嘗試使用powerMockito返回的AmazonEC2

@RunWith(PowerMockRunner.class) 
@PrepareForTest({AwsConfigurationLocal.class})//assuming this is your test class 

@InjectMocks 
private AwsConfigurationLocal subject=PowerMockito.spy(AwsConfigurationLocal.class);//or try Mockito.spy instead, whichever works 

@Test 
    public void TestgetAllSecurityGroups() throws Exception { 

     ec2 = Mockito.mock(AmazonEC2Client.class); 
     PowerMockito.doReturn(ec2).when(subject).configSetter().withNoArguments(); 
     //your code 
    }