因此,我正在尝试进行与我正在实施的服务相关的 Azure 表和 Blob 测试。但是当我进行测试时,它说“无法模拟 TableServiceClient / TableClient,因为它们是最终类”(blob 也会发生同样的情况)。此外,当使用 Autowired 时,它会被检测为空。
接下来是我要测试的代码,但主要问题是无法模拟 TableClient 和 TableServiceClient,因此我无法使用或模拟我创建的表的用法。
@Service
public class AzureServicesTables implements PreferencesPersistenceService {
public final TableServiceClient tableServiceClient;
private final String PARTITION_KEY = "PartitionKey";
@Autowired
public AzureStoragePreferencesPersistenceServiceImpl(TableServiceClient tableServiceClient) {
this.tableServiceClient = tableServiceClient;
}
/**
* This method obtains preferences from Azure Table Storage, returning default preferences
* when user has no setup. The steps are:
* - Get user preferences from Azure Table
* - If user preferences are null, get default preferences
*/
public String getUserPreferencesField(String user) {
TableClient tableClient = this.tableServiceClient.getTableClient("Preferences");
// Query of user preferences
TableEntity entity = null;
try {
entity = tableClient.getEntity(PARTITION_KEY, user);
}
catch (Exception ex) {
// Exception has to be voided in order to get default preferences
LOGGER.info("User preferences not found: "+ex.getClass().getName());
}
// or default preferences if the user has no preferences defined
if (entity == null) {
entity = tableClient.getEntity(PARTITION_KEY, "default");
}
// Getting preferences values from entity
String result = String.valueOf(entity.getProperties().get("value"));
return result;
}
/**
* Saves full preferences for the specified user
* @param user User to which preferences belongs
* @param preferences Preferences to be saved
*/
private Preferences savePreferences(String user, String preferences) {
PreferencesEntity entity = new PreferencesEntity(PARTITION_KEY, user, preferences);
TableClient tableClient = this.tableServiceClient.getTableClient("Preferences");
tableClient.upsertEntity(entity.toTableEntity());
return entity.getPreferences();
}
/**
* This method obtains preferences from Azure Table Storage, returning default preferences
* when user has no setup. The steps are:
* - Get user preferences from Azure Table
* - If user preferences are null, get default preferences
* - Deserialize preferences to return DTO
* @param user The user which user preferences belongs to
* @return User preferences for the specified user
*/
@Override
public Preferences getUserPreferences(String user) {
// JSON deserialization of user preferences
return Preferences.buildFromJson(
this.getUserPreferencesField(user));
}
/**
* This method sets one specified user preference to the value specified. The resulting
* preferences are validated before being saved.
*
* @param user The user to which the preferences belong to
* @param preference Preference to be set
* @param value Value to be set to the preference
* @return Preferences which belongs to the user once modified
*/
@Override
public Preferences setUserPreference(String user, String preference, String value) {
// Value assignment for user preferences. It is done this way, instead of getting value String
// directly in order to have all the properties in the JSON object, not only that have been
// specifically put on current preferences.
DocumentContext jsonPreferences = JsonPath.parse(
this.getUserPreferences(user).jsonString());
jsonPreferences.set("$.."+preference, value);
// Preferences persistence on database
return this.savePreferences(user, jsonPreferences.jsonString());
}
}
'无法模拟 TableServiceClient / TableClient,因为它们是最终类。
我们无法使用 Mockito 等流行的模拟库直接模拟最终类或方法。
PowerMockito框架中的
@MockedStatic
功能来模拟最终类和方法。依赖关系:
<!-- PowerMock dependencies -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<!-- Mockito dependency -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
<!-- JUnit dependency (if not already included) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
检查以下代码以模拟测试方法中的
getTableClient
方法。
import static org.mockito.Mockito.*;
import static org.powermock.api.mockito.PowerMockito.*;
@ExtendWith({PowerMockExtension.class, MockitoExtension.class})
@PrepareForTest({TableServiceClient.class, TableClient.class})
public class AzureServicesTablesTest {
@Test
public void testGetUserPreferencesField() {
// Mock the static method getTableClient of TableServiceClient
try (MockedStatic<TableServiceClient> tableServiceClientMockedStatic = mockStatic(TableServiceClient.class)) {
TableServiceClient tableServiceClientMock = mock(TableServiceClient.class);
TableClient tableClientMock = mock(TableClient.class);
// Define your expected behavior for the mocks
when(tableServiceClientMock.getTableClient("Preferences")).thenReturn(tableClientMock);
// Now, invoke your method under test and perform assertions
AzureServicesTables azureServicesTables = new AzureServicesTables(tableServiceClientMock);
String result = azureServicesTables.getUserPreferencesField("user");
}
}
}
tableServiceClientMock
和 tableClientMock
来控制被测代码的行为并根据需要执行断言。参考: