Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在单元测试中,运行实代码而不是函数存根&;模拟对象_Java_Unit Testing_Amazon S3_Mockito - Fatal编程技术网

Java 在单元测试中,运行实代码而不是函数存根&;模拟对象

Java 在单元测试中,运行实代码而不是函数存根&;模拟对象,java,unit-testing,amazon-s3,mockito,Java,Unit Testing,Amazon S3,Mockito,这是一个非常简单的单元测试用例 我在学校有两种方法: protected S3Object getAwsObject(AmazonS3Client client, String bucketName, String keyName) { GetObjectRequest objRequest = new GetObjectRequest(bucketName, keyName); return client.getObject(objRequest); } 上

这是一个非常简单的单元测试用例

我在学校有两种方法:

protected S3Object getAwsObject(AmazonS3Client client, String bucketName, String keyName) {
        GetObjectRequest objRequest =  new GetObjectRequest(bucketName, keyName);
        return client.getObject(objRequest);
}
上述方法由第二个方法调用,如下所示:

public void doTask() {
   // get client
   AmazonS3Client client = getAwsS3Client();
   // invoke the 1st method
   S3Object s3Obj = getAwsObject(client, "my-bucket", "my-key");
   ...
}
我用来测试方法
doTask()
,我试图模拟
AmazonS3Client
&存根函数
getAwsObject()

运行测试时,我遇到以下错误:

com.amazonaws.services.s3.model.AmazonS3Exception: 
The AWS Access Key Id you provided does not exist in our records. 

(Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; Request ID: 6B973FC095C28524),...

看起来测试用例运行的是真正的代码
client.getObject(objRequest)
,而不是使用
getAwsObject(…)
的存根,为什么?

如果模拟没有成功,可以通过以下方式覆盖原始方法来解决问题:

// mock the client & s3 object
final AmazonS3Client mockedClient = Mockito.mock(AmazonS3Client.class);
final S3Object mockedS3Obj = Mockito.mock(S3Object.class);

School school = new School(){

  @Override
  protected S3Object getAwsObject(AmazonS3Client client, String bucketName, String keyName) {
    return mockedS3Obj;
  }

  @Override
  protected AmazonS3Client getAwsS3Client() {
    return mockedClient;
  }

};

// system under test
school.doTask();

首先,您不应该在遗留代码中使用spy。(). 如果您在非静态工厂/构建器中委托对象的创建,则很容易进行测试

但是,在这种情况下,如果mockito执行真正的代码,那么您的doReturn。。。无效。我认为Mockito不会验证params子句,然后它也不会启动doReturn子句

你有

doReturn...getAwsObject(mockedClient, "my-bucket", "my-key")
如果你做了下一步,并且成功了,那么我100%是对的

doReturn...getAwsObject(any(AmazonS3Client.class), anyString(), anyString())
在同一个语句中使用mock params和not mock params时,我遇到了问题。试试这个:

getAwsObject(mockedClient, eq("my-bucket"), eq("my-key")); 
如果这不起作用,请尝试其他解决方案,如:

eq(mockedClient), eq(...), eq(...)

最后,如果它不起作用,也许@max解决方案会更容易。

这里做了很多错误的事情。
  • 不应为测试中的类创建Spy。
  • 单元测试是为整个班级编写的,用于测试班级中的行为。如果同一类中的方法被模拟,那么单元测试的目的是什么?
  • 应该只模拟依赖类,并且可能提供setter方法来设置这些依赖项。这样就可以决定是注入真实对象还是模拟对象。

    如何将模拟注入对象?相反,您认为它如何在一个不带参数的方法内完成,并且在
    Amazon3Client
    的实例中发布消息?正如您在我的代码中看到的,我使用Mockito.doReturn(mockedObject).when(schoolSpy).any_school_函数()在调用函数时返回mocked对象。从我们看到的情况来看,我们无法证明这些模拟是被注入的。我看到
    S3Object
    amazon3client
    都是类。而不是接口。我假设Mockito在调用
    mock
    方法时调用它们的默认构造函数。尝试使用接口而不是类。例如,
    AmazonS3
    而不是
    AmazonS3Client
    Serializable
    而不是
    S3Object
    我只是尝试复制你的示例。使用
    mockito core 1.10.19
    一切正常。(
    getAwsObject()
    通过模拟客户端调用,并返回模拟对象。
    eq(mockedClient), eq(...), eq(...)