【问题标题】:Mocking not able to mock method call模拟无法模拟方法调用
【发布时间】:2017-03-29 17:43:15
【问题描述】:

我试图在我的测试中模拟一个调用,但我得到一个错误,因为它调用真实方法而不是模拟它。

这是我的方法

@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 并在设置代理时失败。帮助我了解我在这里做错了什么。

【问题讨论】:

  • 能否提供带有顶级注释的完整测试类的代码?
  • @javaguy 你的意思是在我的主题类中自动装配 AwsService ?
  • 您的测试期望 awsService.getAllSecurityGroups() 以 yoyr mocked ec2 作为参数调用。但是您的代码不会使用您的模拟 ec2 调用它。它使用调用 configSetter() 创建的 ec2 调用它

标签: java testing junit mockito


【解决方案1】:

subject.getAllSecurityGroups(); 调用真实的configSetter(),它返回真实的AmazonEC2,然后传递给awsService.getAllSecurityGroups(ec2);。该参数与您的模拟 ec2 不匹配,因此默认模拟实现作为 actual 返回(我猜它是空的)。

所以问题是:没有什么可以阻止configSetter() 的真正实现被调用。 如果你用 @Spy 注释 subject 并做

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

它应该按预期工作。

话虽如此,有很多设置只是为了检查被委托的简单调用。这是AwsConfigurationLocal 中两个职责的混合——创建AmazonEC2Client 和提供getAllSecurityGroups()。如果您将前者移到单独的类中(比如说AmazonEC2ClientFactor),一切都应该到位。

【讨论】:

  • 用@spy 注释和模拟Mockito.when(subject.configSetter()).then(ec2); 有相同的结果。它调用了真正的方法。此类用于创建 AmazonEC2Client,而 getAllSecurityGroup 将调用委托给另一个类。我有这个方法 configSetter 作为它在这个类中的常用方法。
【解决方案2】:

尝试使用 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
    }

【讨论】:

    猜你喜欢
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 2021-07-26
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多