如何模拟Azure PagedIterable<T>

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

我有一个 Java Springboot Web API 项目,它使用 Azure 表存储作为数据存储。我想创建一个单元测试,以确保存储库正确地将 Azure

TableEntity
转换为存储库中的自定义
Tag
对象。但是,我无法找到一种方法来模拟 Azure
PagedIterable<TableEntity>
函数返回的 Azure
TableClient.listEntities()

我的存储库类的核心是以下函数,它返回经过过滤的表实体列表:

    private PagedIterable<TableEntity> getFilteredTableRows(String filter, String tableName) {
        ListEntitiesOptions options = new ListEntitiesOptions().setFilter(filter);
        TableClient tableClient = tableServiceClient.getTableClient(tableName);
        PagedIterable<TableEntity> pagedIterable = tableClient.listEntities(options, null, null);
        return pagedIterable;
    }

如何确保

TableClient
被模拟并返回有效的
PagedIterable<TableEntity>

java spring azure-table-storage
2个回答
2
投票

下面是示例 JUnit 测试类,它使用 Mockito 模拟 Azure

PagedIterable<T>
对象并返回映射到存储库代码中的自定义标签模型的单个
TableEntity

测试设置需要四个模拟:

  1. 模拟迭代器
  2. 模拟PagedIterable
  3. 模拟 TableServiceClient
  4. 模拟 TableClient

如果有更简单的方法来完成同样的事情,我愿意接受建议。

@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class DocTagRepositoryTest {

    @InjectMocks
    @Spy
    DocTagRepository docTagRepository;

    @Mock
    TableServiceClient tableServiceClient;

    @Mock
    TableClient tableClient;

    private static TableEntity testTableEntity;
    private static Tag testTagObject;

    @SneakyThrows
    @BeforeAll
    public static void setup() {
        loadTableObjects();
    }

    @Test
    public void testGetTagList() {
        // Given: A request to get tags from Azure table storage...
        Iterator mockIterator = mock(Iterator.class);
        when(mockIterator.hasNext()).thenReturn(true, false);
        when(mockIterator.next()).thenReturn(testTableEntity);

        PagedIterable mockPagedTableEntities = mock(PagedIterable.class);
        when(mockPagedTableEntities.iterator()).thenReturn(mockIterator);

        when(tableServiceClient.getTableClient(Mockito.anyString())).thenReturn(tableClient);
        when(tableClient.listEntities(any(), any(), any())).thenReturn(mockPagedTableEntities);

        List<Tag> expected = new ArrayList<>();
        expected.add(testTagObject);

        // When: A call is made to the repository's getActiveTags() function...
        List<Tag> actual = docTagRepository.getActiveTags();

        // Then: Return an array of tag objects.
        assertArrayEquals(expected.toArray(), actual.toArray());
    }

    private static void loadTableObjects() {
        OffsetDateTime now = OffsetDateTime.now();
        String testUser = "buh0000";
        String rowKey = "test";
        String partitionKey = "v1";
        String activeStatus = "A";
        Map<String, Object> properties = new HashMap<>();
        properties.put("createdDate", now);
        properties.put("createdBy", testUser);
        properties.put("modifiedDate", now);
        properties.put("lastModifiedBy", testUser);
        properties.put("status", activeStatus);

        testTableEntity = new TableEntity(partitionKey, rowKey);
        testTableEntity.setProperties(properties);

        testTagObject = new Tag(partitionKey, rowKey, now, testUser, now, testUser, activeStatus);
    }
}

0
投票

好吧,还有更好的方法。将所需数据放入 List 中,然后传递 List 迭代器而不是 PagedIterable 的迭代器。这不需要迭代器的模拟。以下是来自(kotlin)的代码片段:

    val update1 = BinaryData.fromString("some string")
    val listUpdate = mutableListOf<BinaryData>(update1) // list of data

    val pagedIterable: PagedIterable<BinaryData> = mockk() // mockking for iterator
    every {
        pagedIterable.iterator()
    } returns listUpdate.iterator()

    mockkConstructor(xxxx::class) // Mock the SDK API to return pagedIterable
    every {
        anyConstructed<xxxx>().APICalledWhichReturnsPagedIterableType(any())
    } answers {
        pagedIterable
    }
© www.soinside.com 2019 - 2024. All rights reserved.