couchbase 7.2 升级后数据库调用 java 代码的测试覆盖率

问题描述 投票:0回答:1

我们最近将 Couchbase DB 从 6.x 升级到了 7.2。其中介绍了集合和范围以及存储桶。就是这个意思

        GetResult serviceInventoryJsonDocument =      this.bucket.defaultCollection().get(this.getDocumentId(serviceInstanceId));

替换为

        GetResult serviceInventoryJsonDocument =
                      bucket.scope(bucketScope).collection(bucketCollection).get(getDocumentId(serviceInstanceId));

我的存储库类是

    @Primary
    @Repository
    public class AccessServiceInventoryRepositoryImpl extends ServiceInventoryRepositoryImpl
        implements AccessServiceInventoryRepository {

    private final Logger log = LoggerFactory.getLogger(getClass());
    private final Gson gson = new Gson();
    private static final String CALL_BUCKET_REPLACE = "We are going to call bucket.replace";
    private static final String SELECT_FROM = "select * from ";

    @Autowired
    public AccessServiceInventoryRepositoryImpl(final ServiceInventoryMethodsValidator     serviceInventoryMethodsValidator,
            final CouchbaseConfigProperties couchbaseConfigProperties,
            final MicroserviceConfigProperties microserviceConfigProperties,
            final DomainServiceInventoryConfigProperties domainServiceInventoryConfigProperties) {
        super(serviceInventoryMethodsValidator, couchbaseConfigProperties,
                microserviceConfigProperties, domainServiceInventoryConfigProperties);
    }

    @Override
    public AccessServiceInventory getServiceInventoryById(final String serviceInstanceId)
            throws ServiceInventoryException {
        log.debug("{} retrieving service inventory by ID {}", getClass().getSimpleName(),
                getDocumentId(serviceInstanceId));
        final GetResult serviceInventoryJsonDocument =
                    bucket.scope(bucketScope).collection(bucketCollection).get(getDocumentId(serviceInstanceId));
        if (serviceInventoryJsonDocument == null) {
            throw new ServiceInventoryException("No results returned, processing timeout.");
        }
        return gson.fromJson(serviceInventoryJsonDocument.contentAsObject().toString(),      AccessServiceInventory.class);
    }
    }

我当前的junit测试课如下

    @RunWith(MockitoJUnitRunner.class) @Ignore
    public class AccessServiceInventoryRepositoryImplTest {

    @Mock
    private Bucket bucket;
    @Mock
    private Cluster cluster;
    @Mock
    private Collection collectionBucket;
    @Mock
    private GetResult getResult;
    @Mock
    private QueryResult queryResult;
    @Mock
    private QueryMetaData queryMetaData;
    @Mock
    private ServiceInventoryMethodsValidator serviceInventoryMethodsValidator;
    private AccessServiceInventoryRepositoryImpl repositoryImpl;
    @Before
    public void setup() throws NoSuchFieldException, IllegalAccessException {

        repositoryImpl = new AccessServiceInventoryRepositoryImpl(
                serviceInventoryMethodsValidator,
                CouchbaseBucketConfig.getCouchbaseConfig(), CouchbaseBucketConfig.getMicroserviceConfigProperties(),
                new DomainServiceInventoryConfigProperties());
        ReflectionTestUtils.setField(repositoryImpl, "cluster", cluster);
        final Field bucketField = ServiceInventoryRepositoryImpl.class.getDeclaredField("bucket");
        bucketField.setAccessible(true);
        bucketField.set(repositoryImpl, bucket);
        when(bucket.defaultCollection()).thenReturn(collectionBucket);
        when(collectionBucket
                .get(anyString())).thenReturn(getResult);
    }

    @Test(expected = ServiceInventoryException.class)
    public void getServiceInventoryByIdShouldThrowServiceInventoryExceptionWhenJsonDocumentIsNull() throws     Exception {
        when(bucket.defaultCollection().get(anyString())).thenReturn(null);
        repositoryImpl.getServiceInventoryById("123456");
    }

我尝试过更改测试用例

when(bucket.defaultCollection().get(anyString())).thenReturn(null);

    when(bucket.scope(anyString())).thenReturn(scope);
        when(scope.collection(anyString())).thenReturn(collection);
        when(collection.get(anyString())).thenReturn(null);

但遇到同样的异常

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.couchbase.client.java.Scope.
org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.couchbase.client.java.Collection
Mockito can only mock non-private & non-final classes, but the root cause of this error might be different.

我什至在 CouchbaseConfigProperties 中将集合和范围设置为非私有和非最终,但仍然遇到相同的错误 我想要这个工作

spring-boot unit-testing junit mockito couchbase
1个回答
0
投票

这就是为什么有些人说你应该只模拟你拥有的类型

您可以通过改变测试方式和内容来解决这个问题。更改应用程序的设计也会有所帮助。

在某些时候,您可能需要针对真实的 Couchbase Server 集群运行测试。我强烈建议使用 TestContainers 来实现这一点。它有一个运行良好的 Couchbase 模块

一旦您进行了与真实服务器通信的测试,您可以问自己模拟是否仍然提供价值(或者如果每次升级依赖项时模拟都会中断,那么模拟可能是一种责任)。

在应用程序设计方面,您可以围绕 Couchbase Java SDK 创建一个小包装器。您的包装器可以是一个易于模拟的接口。您无需模拟 Couchbase SDK 的类和方法,而是模拟包装器的方法。

实际上,无论如何,我都会推荐包装器方法,这样您就可以应对 Couchbase SDK API 未来可能发生的更改。一般来说,包装器还可以保护您免受后端锁定。 (免责声明:我在 Couchbase 工作。我们希望您使用 Couchbase 是因为您喜欢它,而不是因为您无力切换到其他产品。)

© www.soinside.com 2019 - 2024. All rights reserved.