From 6319e421f7009ab779c57f77c51105d865842bef Mon Sep 17 00:00:00 2001 From: wcj Date: Tue, 9 Sep 2025 23:13:35 +0800 Subject: [PATCH 1/5] RAF TDD Change-Id: I0d2d3077e5889660129c13936a74dbb877717f79 --- interfaces/test/unittest/js/BUILD.gn | 41 ++++- .../mock/randomaccessfile_n_exporter_mock.cpp | 159 ++++++++++++++++++ .../mock/randomaccessfile_n_exporter_mock.h | 65 +++++++ .../randomaccessfile_n_exporter_mock_test.cpp | 103 ++++++++++++ 4 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp create mode 100644 interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h create mode 100644 interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp diff --git a/interfaces/test/unittest/js/BUILD.gn b/interfaces/test/unittest/js/BUILD.gn index f0326f9b2..ef45eb3ad 100644 --- a/interfaces/test/unittest/js/BUILD.gn +++ b/interfaces/test/unittest/js/BUILD.gn @@ -324,27 +324,66 @@ ohos_unittest("napi_file_fs_test") { module_out_path = "file_api/file_api" - include_dirs = [ "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher" ] + include_dirs = [ + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_randomaccessfile", + "${file_api_path}/interfaces/kits/js/src/common", + "${file_api_path}/interfaces/kits/js/src/common/file_helper", + "${file_api_path}/interfaces/kits/js/src/mod_fs", + "${utils_path}/common/include", + "mod_fs/properties/mock", + "mod_fs/class_randomaccessfile/mock", + ] sources = [ "${file_api_path}/interfaces/kits/js/src/mod_fs/class_watcher/watcher_entity.cpp", + "${file_api_path}/interfaces/kits/js/src/common/file_helper/fd_guard.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/common_func.cpp", "mod_fs/class_watcher/watcher_entity_test.cpp", + "mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp", + "mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp", + "mod_fs/properties/mock/uv_fs_mock.cpp", ] deps = [ "${file_api_path}/interfaces/kits/js:fs", + "${file_api_path}/interfaces/kits/native:remote_uri_native", "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", "${utils_path}/filemgmt_libn:filemgmt_libn", ] external_deps = [ + "ability_base:zuri", "c_utils:utils", + "googletest:gmock_main", "googletest:gtest_main", "hilog:libhilog", "libuv:uv", "napi:ace_napi", + "app_file_service:fileuri_native", + "ipc:ipc_core", + "samgr:samgr_proxy", ] + include_dirs += [ "${file_api_path}/interfaces/kits/rust/include" ] + + external_deps += [ + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "access_token:libtokenid_sdk", + "app_file_service:fileuri_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "data_share:datashare_common", + "data_share:datashare_consumer", + "dfs_service:distributed_file_daemon_kit_inner", + "dfs_service:libdistributedfileutils", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + defines = [ "private=public" ] use_exceptions = true diff --git a/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp new file mode 100644 index 000000000..aef023ef0 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "randomaccessfile_n_exporter_mock.h" + #include "n_class.h" + + #include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptr + RandomAccessFileNExporterMock::randomAccessFileNExporterMock = nullptr; +thread_local bool RandomAccessFileNExporterMock::mockable = false; + +std::shared_ptr RandomAccessFileNExporterMock::GetMock() +{ + if (randomAccessFileNExporterMock == nullptr) { + randomAccessFileNExporterMock = std::make_shared(); + } + return randomAccessFileNExporterMock; +} + +void RandomAccessFileNExporterMock::EnableMock() +{ + mockable = true; +} + +void RandomAccessFileNExporterMock::DisableMock() +{ + randomAccessFileNExporterMock = nullptr; + mockable = false; +} + +bool RandomAccessFileNExporterMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +bool NFuncArg::InitArgs(std::function argcChecker) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->InitArgs(argcChecker); + } + + static bool (*realInitArgs)(std::function) = []() { + auto func = (bool(*)(std::function))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argcChecker); +} + +napi_value NFuncArg::GetThisVar() const +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->GetThisVar(); + } + + static napi_value (*realGetThisVar)() = []() { + auto func = (napi_value(*)())dlsym(RTLD_NEXT, "GetThisVar"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetThisVar: " << dlerror(); + } + return func; + }(); + + if (!realGetThisVar) { + return nullptr; + } + + return realGetThisVar(); +} + +napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->napi_unwrap(env, js_object, result); + } + + static napi_status (*realNapi)(napi_env, napi_value, void **) = []() { + auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_unwrap"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real napi_unwrap: " << dlerror(); + } + return func; + }(); + + if (!realNapi) { + return napi_ok; + } + + return realNapi(env, js_object, result); +} + +napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->napi_remove_wrap(env, js_object, result); + } + + static napi_status (*realNapi)(napi_env, napi_value, void **) = []() { + auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_remove_wrap"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real napi_remove_wrap: " << dlerror(); + } + return func; + }(); + + if (!realNapi) { + return napi_ok; + } + + return realNapi(env, js_object, result); +} + +NVal NVal::CreateUndefined(napi_env env) +{ + if (RandomAccessFileNExporterMock::IsMockable()) { + return RandomAccessFileNExporterMock::GetMock()->CreateUndefined(env); + } + + static NVal (*realCreateUndefined)(napi_env) = []() { + auto func = (NVal(*)(napi_env))dlsym(RTLD_NEXT, "CreateUndefined"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real CreateUndefined: " << dlerror(); + } + return func; + }(); + + if (!realCreateUndefined) { + return {nullptr, nullptr}; + } + + return realCreateUndefined(env); +} \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h new file mode 100644 index 000000000..17df0d8a8 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/mock/randomaccessfile_n_exporter_mock.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_TEST_UNITTEST_RANDOMACCESSFILENEXPORTER_MOCK_H +#define INTERFACES_TEST_UNITTEST_RANDOMACCESSFILENEXPORTER_MOCK_H + +#include "filemgmt_libn.h" +#include "randomaccessfile_n_exporter.h" +#include "randomaccessfile_entity.h" + +#include +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; + +class IRandomAccessFileNExporterMock { +public: + virtual ~IRandomAccessFileNExporterMock() = default; + virtual bool InitArgs(std::function argcChecker) = 0; + virtual napi_value GetThisVar() = 0; + virtual napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) = 0; + virtual napi_status napi_remove_wrap(napi_env env, napi_value js_object, void **result) = 0; + virtual RandomAccessFileEntity* RemoveEntityOfFinal(napi_env env, napi_value napi_value) = 0; + virtual NVal CreateUndefined(napi_env env) = 0; +}; + +class RandomAccessFileNExporterMock : public IRandomAccessFileNExporterMock { +public: +MOCK_METHOD(bool, InitArgs, (std::function), (override)); +MOCK_METHOD(napi_value, GetThisVar, (), (override)); +MOCK_METHOD(napi_status, napi_unwrap, (napi_env, napi_value, void **), (override)); +MOCK_METHOD(napi_status, napi_remove_wrap, (napi_env, napi_value, void **), (override)); +MOCK_METHOD(RandomAccessFileEntity*, RemoveEntityOfFinal, (napi_env, napi_value), (override)); +MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr randomAccessFileNExporterMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_RANDOMACCESSFILENEXPORTER_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp new file mode 100644 index 000000000..512a97d0b --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/class_randomaccessfile/randomaccessfile_n_exporter_mock_test.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "randomaccessfile_n_exporter.h" +#include "randomaccessfile_entity.h" +#include "uv_fs_mock.h" +#include "randomaccessfile_n_exporter_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class RandomAccessFileNExporterMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +protected: + unique_ptr rafEntity; +}; + +void RandomAccessFileNExporterMockTest::SetUpTestCase(void) +{ + uvMock = make_shared(); + Uvfs::ins = uvMock; + RandomAccessFileNExporterMock::EnableMock(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void RandomAccessFileNExporterMockTest::TearDownTestCase(void) +{ + Uvfs::ins = nullptr; + uvMock = nullptr; + RandomAccessFileNExporterMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void RandomAccessFileNExporterMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + rafEntity = make_unique(); + const int fdValue = 3; + const bool isClosed = false; + rafEntity->fd = make_unique(fdValue, isClosed); + rafEntity->filePointer = 0; + +} + +void RandomAccessFileNExporterMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: RandomAccessFileNExporterMockTest_CloseSync_001 + * @tc.desc: Test function of CloseSync() interface for success. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + +*/ +HWTEST_F(RandomAccessFileNExporterMockTest, RandomAccessFileNExporterMockTest_CloseSync_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "RandomAccessFileNExporterMockTest-begin RandomAccessFileNExporterMockTest_CloseSync_001"; + napi_env env = reinterpret_cast(0x1000); + napi_callback_info mInfo = reinterpret_cast(0x1122); + napi_value nv = reinterpret_cast(0x1200); + NVal mockNval = {env, nv}; + + auto rafNEMock = RandomAccessFileNExporterMock::GetMock(); + EXPECT_CALL(*rafNEMock, InitArgs(_)).WillOnce(Return(true)); + EXPECT_CALL(*rafNEMock, GetThisVar()).WillOnce(Return(nv)).WillOnce(Return(nv)); + EXPECT_CALL(*rafNEMock, napi_unwrap(_, _, _)) + .WillOnce(DoAll(SetArgPointee<2>(static_cast(rafEntity.get())), Return(napi_ok))); + EXPECT_CALL(*uvMock, uv_fs_close(_, _, _, _)).WillOnce(Return(0)); + EXPECT_CALL(*rafNEMock, napi_remove_wrap(_, _, _)) + .WillOnce(DoAll(SetArgPointee<2>(static_cast(rafEntity.get())), Return(napi_ok))); + EXPECT_CALL(*rafNEMock, CreateUndefined(_)).WillOnce(Return(mockNval)); + + auto res = RandomAccessFileNExporter::CloseSync(env, mInfo); + EXPECT_NE(res, nullptr); + + GTEST_LOG_(INFO) << "RandomAccessFileNExporterMockTest-end RandomAccessFileNExporterMockTest_CloseSync_001"; +} + +} \ No newline at end of file -- Gitee From d9e63f3ad9cd16775eb77e6737e95042ec96a26f Mon Sep 17 00:00:00 2001 From: wcj Date: Wed, 10 Sep 2025 21:09:14 +0800 Subject: [PATCH 2/5] fdatasync TDD Change-Id: I649d7fcf91e395b196fcddc3efb159bd1194cd44 --- interfaces/test/unittest/BUILD.gn | 1 + interfaces/test/unittest/napi_js/BUILD.gn | 83 +++++++++ .../unittest/napi_js/fdatasync_mock_test.cpp | 94 +++++++++++ .../unittest/napi_js/mock/fdatasync_mock.cpp | 158 ++++++++++++++++++ .../unittest/napi_js/mock/fdatasync_mock.h | 65 +++++++ 5 files changed, 401 insertions(+) create mode 100644 interfaces/test/unittest/napi_js/BUILD.gn create mode 100644 interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp create mode 100644 interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp create mode 100644 interfaces/test/unittest/napi_js/mock/fdatasync_mock.h diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 9a3e2915e..2bc34018f 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -28,6 +28,7 @@ group("file_api_unittest") { "js:napi_file_fs_test", "remote_uri:remote_uri_test", "task_signal:task_signal_test", + "napi_js:napi_file_fs_properties_test", ] if (file_api_feature_hyperaio) { deps += [ "hyperaio:hyperaio_test" ] diff --git a/interfaces/test/unittest/napi_js/BUILD.gn b/interfaces/test/unittest/napi_js/BUILD.gn new file mode 100644 index 000000000..251cf6824 --- /dev/null +++ b/interfaces/test/unittest/napi_js/BUILD.gn @@ -0,0 +1,83 @@ +# Copyright (C) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/filemanagement/file_api/file_api.gni") + +ohos_unittest("napi_file_fs_properties_test") { + branch_protector_ret = "pac_ret" + testonly = true + + module_out_path = "file_api/file_api" + + include_dirs = [ + "${file_api_path}/interfaces/kits/js/src/common", + "${file_api_path}/interfaces/kits/js/src/common/file_helper", + "${file_api_path}/interfaces/kits/js/src/mod_fs", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", + "${utils_path}/common/include", + "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock", + "mock", + ] + + sources = [ + "${file_api_path}/interfaces/kits/js/src/common/file_helper/fd_guard.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/common_func.cpp", + "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp", + "mock/fdatasync_mock.cpp", + "fdatasync_mock_test.cpp", + ] + + deps = [ + "${file_api_path}/interfaces/kits/js:fs", + "${file_api_path}/interfaces/kits/native:remote_uri_native", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + "${utils_path}/filemgmt_libn:filemgmt_libn", + ] + + external_deps = [ + "ability_base:zuri", + "c_utils:utils", + "googletest:gmock_main", + "googletest:gtest_main", + "hilog:libhilog", + "libuv:uv", + "napi:ace_napi", + "app_file_service:fileuri_native", + "ipc:ipc_core", + "samgr:samgr_proxy", + ] + + include_dirs += [ "${file_api_path}/interfaces/kits/rust/include" ] + + external_deps += [ + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "access_token:libtokenid_sdk", + "app_file_service:fileuri_native", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "data_share:datashare_common", + "data_share:datashare_consumer", + "dfs_service:distributed_file_daemon_kit_inner", + "dfs_service:libdistributedfileutils", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", + ] + + defines = [ "private=public" ] + + use_exceptions = true +} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp new file mode 100644 index 000000000..3c1c1c082 --- /dev/null +++ b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "fdatasync.h" +#include "uv_fs_mock.h" +#include "fdatasync_mock.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class FdatasyncMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +protected: + +}; + +void FdatasyncMockTest::SetUpTestCase(void) +{ + uvMock = make_shared(); + Uvfs::ins = uvMock; + FdatasyncMock::EnableMock(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void FdatasyncMockTest::TearDownTestCase(void) +{ + Uvfs::ins = nullptr; + uvMock = nullptr; + FdatasyncMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void FdatasyncMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + +} + +void FdatasyncMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: FdatasyncMockTest_Sync_001 + * @tc.desc: Test function of Sync() interface for uv_fs_fdatasync failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + +*/ +HWTEST_F(FdatasyncMockTest, FdatasyncMockTest_CloseSync_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FdatasyncMockTest-begin FdatasyncMockTest_Sync_001"; + napi_env env = reinterpret_cast(0x1000); + napi_value nv = reinterpret_cast(0x1200); + napi_callback_info mInfo = reinterpret_cast(0x1122); + tuple tp = {true, 1}; + + auto FdatasyncMock = FdatasyncMock::GetMock(); + EXPECT_CALL(*FdatasyncMock, InitArgs(_)).WillOnce(Return(true)); + EXPECT_CALL(*FdatasyncMock, GetArg(_)).WillOnce(Return(nv)); + EXPECT_CALL(*FdatasyncMock, ToInt32()).WillOnce(Return(tp)); + EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(1)); + EXPECT_CALL(*FdatasyncMock, ThrowErr(_, _)); + + auto res = Fdatasync::Sync(env, mInfo); + EXPECT_EQ(res, nullptr); + + GTEST_LOG_(INFO) << "FdatasyncMockTest-end FdatasyncMockTest_Sync_001"; +} + +} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp new file mode 100644 index 000000000..d030adabc --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fdatasync_mock.h" + #include "n_class.h" + + #include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptrFdatasyncMock::fdatasyncMock = nullptr; +thread_local bool FdatasyncMock::mockable = false; + +std::shared_ptr FdatasyncMock::GetMock() +{ + if (fdatasyncMock == nullptr) { + fdatasyncMock = std::make_shared(); + } + return fdatasyncMock; +} + +void FdatasyncMock::EnableMock() +{ + mockable = true; +} + +void FdatasyncMock::DisableMock() +{ + fdatasyncMock = nullptr; + mockable = false; +} + +bool FdatasyncMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +bool NFuncArg::InitArgs(std::function argcChecker) +{ + if (FdatasyncMock::IsMockable()) { + return FdatasyncMock::GetMock()->InitArgs(argcChecker); + } + + static bool (*realInitArgs)(std::function) = []() { + auto func = (bool(*)(std::function))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argcChecker); +} + +napi_value NFuncArg::GetArg(size_t argPos) const +{ + if (FdatasyncMock::IsMockable()) { + return FdatasyncMock::GetMock()->GetArg(argPos); + } + + static napi_value (*realGetArg)(size_t) = []() { + auto func = (napi_value(*)(size_t))dlsym(RTLD_NEXT, "GetArg"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetArg: " << dlerror(); + } + return func; + }(); + + if (!realGetArg) { + return nullptr; + } + + return realGetArg(argPos); +} + +tuple NVal::ToInt32() const +{ + if (FdatasyncMock::IsMockable()) { + return FdatasyncMock::GetMock()->ToInt32(); + } + + static tuple (*realToInt32)() = []() { + auto func = (tuple(*)())dlsym(RTLD_NEXT, "ToInt32"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt32: " << dlerror(); + } + return func; + }(); + + if (!realToInt32) { + return {false, 0}; + } + + return realToInt32(); +} + +NVal NVal::CreateUndefined(napi_env env) +{ + if (FdatasyncMock::IsMockable()) { + return FdatasyncMock::GetMock()->CreateUndefined(env); + } + + static NVal (*realCreateUndefined)(napi_env) = []() { + auto func = (NVal(*)(napi_env))dlsym(RTLD_NEXT, "CreateUndefined"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real CreateUndefined: " << dlerror(); + } + return func; + }(); + + if (!realCreateUndefined) { + return {nullptr, nullptr}; + } + + return realCreateUndefined(env); +} + +void NError::ThrowErr(napi_env env, std::string errMsg) +{ + if (FdatasyncMock::IsMockable()) { + return FdatasyncMock::GetMock()->ThrowErr(env, errMsg); + } + + static void (*realThrowErr)(napi_env, std::string) = []() { + auto func = (void (*)(napi_env, std::string))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errMsg); +} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h new file mode 100644 index 000000000..368a8fe41 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_TEST_UNITTEST_FDATASYNC_MOCK_H +#define INTERFACES_TEST_UNITTEST_FDATASYNC_MOCK_H + +#include "filemgmt_libn.h" +#include "fdatasync.h" + +#include +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; +using std::tuple; + +class IFdatasyncMock { +public: + virtual ~IFdatasyncMock() = default; + virtual bool InitArgs(std::function argcChecker) = 0; + virtual napi_value GetThisVar() = 0; + virtual NVal CreateUndefined(napi_env env) = 0; + virtual napi_value GetArg(size_t argPos) = 0; + virtual tuple ToInt32() = 0; + virtual void ThrowErr(napi_env env, std::string errMsg) = 0; +}; + +class FdatasyncMock : public IFdatasyncMock { +public: +MOCK_METHOD(bool, InitArgs, (std::function), (override)); +MOCK_METHOD(napi_value, GetThisVar, (), (override)); +MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); +MOCK_METHOD(napi_value, GetArg, (size_t), (override)); +MOCK_METHOD((tuple), ToInt32, (), (override)); +MOCK_METHOD(void, ThrowErr, (napi_env, std::string), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr fdatasyncMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_FDATASYNC_MOCK_H \ No newline at end of file -- Gitee From 0463eed282bc88586850f0a42e17259b9d748422 Mon Sep 17 00:00:00 2001 From: wcj Date: Thu, 11 Sep 2025 14:32:25 +0800 Subject: [PATCH 3/5] propNExporter TDD Change-Id: I6d81e3b9f82ff914ad56922fc69ebc57841de988 --- interfaces/test/unittest/napi_js/BUILD.gn | 2 + .../unittest/napi_js/fdatasync_mock_test.cpp | 10 +- .../napi_js/mock/prop_n_exporter_mock.cpp | 54 +++++++++++ .../napi_js/mock/prop_n_exporter_mock.h | 65 +++++++++++++ .../napi_js/prop_n_exporter_mock_test.cpp | 94 +++++++++++++++++++ 5 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp create mode 100644 interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h create mode 100644 interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp diff --git a/interfaces/test/unittest/napi_js/BUILD.gn b/interfaces/test/unittest/napi_js/BUILD.gn index 251cf6824..44365231c 100644 --- a/interfaces/test/unittest/napi_js/BUILD.gn +++ b/interfaces/test/unittest/napi_js/BUILD.gn @@ -37,6 +37,8 @@ ohos_unittest("napi_file_fs_properties_test") { "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp", "mock/fdatasync_mock.cpp", "fdatasync_mock_test.cpp", + "mock/prop_n_exporter_mock.cpp", + "prop_n_exporter_mock_test.cpp", ] deps = [ diff --git a/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp index 3c1c1c082..7966dac69 100644 --- a/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp +++ b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp @@ -78,12 +78,12 @@ HWTEST_F(FdatasyncMockTest, FdatasyncMockTest_CloseSync_001, TestSize.Level1) napi_callback_info mInfo = reinterpret_cast(0x1122); tuple tp = {true, 1}; - auto FdatasyncMock = FdatasyncMock::GetMock(); - EXPECT_CALL(*FdatasyncMock, InitArgs(_)).WillOnce(Return(true)); - EXPECT_CALL(*FdatasyncMock, GetArg(_)).WillOnce(Return(nv)); - EXPECT_CALL(*FdatasyncMock, ToInt32()).WillOnce(Return(tp)); + auto pMock = FdatasyncMock::GetMock(); + EXPECT_CALL(*pMock, InitArgs(_)).WillOnce(Return(true)); + EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); + EXPECT_CALL(*pMock, ToInt32()).WillOnce(Return(tp)); EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(1)); - EXPECT_CALL(*FdatasyncMock, ThrowErr(_, _)); + EXPECT_CALL(*pMock, ThrowErr(_, _)); auto res = Fdatasync::Sync(env, mInfo); EXPECT_EQ(res, nullptr); diff --git a/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp new file mode 100644 index 000000000..21919baea --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "prop_n_exporter_mock.h" + #include "n_class.h" + + #include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptrPropNExporterMock::pPropNExporterMock = nullptr; +thread_local bool PropNExporterMock::mockable = false; + +std::shared_ptr PropNExporterMock::GetMock() +{ + if (pPropNExporterMock == nullptr) { + pPropNExporterMock = std::make_shared(); + } + return pPropNExporterMock; +} + +void PropNExporterMock::EnableMock() +{ + mockable = true; +} + +void PropNExporterMock::DisableMock() +{ + pPropNExporterMock = nullptr; + mockable = false; +} + +bool PropNExporterMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +using namespace OHOS::FileManagement::ModuleFileIO::Test; + diff --git a/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h new file mode 100644 index 000000000..0f8f130eb --- /dev/null +++ b/interfaces/test/unittest/napi_js/mock/prop_n_exporter_mock.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_TEST_UNITTEST_PROPNEXPORTER_MOCK_H +#define INTERFACES_TEST_UNITTEST_PROPNEXPORTER_MOCK_H + +#include "filemgmt_libn.h" +#include "prop_n_exporter.h" + +#include +#include +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; +using std::tuple; + +class IPropNExporterMock { +public: + virtual ~IPropNExporterMock() = default; + virtual bool InitArgs(std::function argcChecker) = 0; + virtual napi_value GetThisVar() = 0; + virtual NVal CreateUndefined(napi_env env) = 0; + virtual napi_value GetArg(size_t argPos) = 0; + virtual tuple ToInt32() = 0; + virtual void ThrowErr(napi_env env, std::string errMsg) = 0; +}; + +class PropNExporterMock : public IPropNExporterMock { +public: +MOCK_METHOD(bool, InitArgs, (std::function), (override)); +MOCK_METHOD(napi_value, GetThisVar, (), (override)); +MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); +MOCK_METHOD(napi_value, GetArg, (size_t), (override)); +MOCK_METHOD((tuple), ToInt32, (), (override)); +MOCK_METHOD(void, ThrowErr, (napi_env, std::string), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr pPropNExporterMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_PROPNEXPORTER_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp b/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp new file mode 100644 index 000000000..2a0de8b4f --- /dev/null +++ b/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "prop_n_exporter_mock.h" +#include "uv_fs_mock.h" +#include "prop_n_exporter.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class PropNExporterMockTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + static inline shared_ptr uvMock = nullptr; +protected: + +}; + +void PropNExporterMockTest::SetUpTestCase(void) +{ + uvMock = make_shared(); + Uvfs::ins = uvMock; + PropNExporterMock::EnableMock(); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void PropNExporterMockTest::TearDownTestCase(void) +{ + Uvfs::ins = nullptr; + uvMock = nullptr; + PropNExporterMock::DisableMock(); + GTEST_LOG_(INFO) << "TearDownTestCase"; +} + +void PropNExporterMockTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; + +} + +void PropNExporterMockTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: PropNExporterMockTest_Sync_001 + * @tc.desc: Test function of Sync() interface for failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + +*/ +HWTEST_F(PropNExporterMockTest, PropNExporterMockTest_CloseSync_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "PropNExporterMockTest-begin PropNExporterMockTest_Sync_001"; + // napi_env env = reinterpret_cast(0x1000); + // napi_value nv = reinterpret_cast(0x1200); + // napi_callback_info mInfo = reinterpret_cast(0x1122); + // tuple tp = {true, 1}; + + // auto pMock = PropNExporterMock::GetMock(); + // EXPECT_CALL(*pMock, InitArgs(_)).WillOnce(Return(true)); + // EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); + // EXPECT_CALL(*pMock, ToInt32()).WillOnce(Return(tp)); + // EXPECT_CALL(*uvMock, uv_fs_PropNExporter(_, _, _, _)).WillOnce(Return(1)); + // EXPECT_CALL(*pMock, ThrowErr(_, _)); + + // auto res = PropNExporter::Sync(env, mInfo); + // EXPECT_EQ(res, nullptr); + + GTEST_LOG_(INFO) << "PropNExporterMockTest-end PropNExporterMockTest_Sync_001"; +} + +} \ No newline at end of file -- Gitee From 80b99b212e231476f0fb9fdcb77e1eef29d186b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E9=91=AB?= Date: Wed, 10 Sep 2025 11:31:17 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=85=AC=E5=85=B1mock=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 周鑫 Change-Id: I44c08bb77da7bd82ca3e45d21d7fff2a8a6440f1 --- interfaces/test/unittest/BUILD.gn | 1 + .../napi_js/mod_fs/mock/libn_mock.cpp | 477 ++++++++++++++++++ .../unittest/napi_js/mod_fs/mock/libn_mock.h | 101 ++++ .../napi_js/mod_fs/mock/uv_fs_mock.cpp | 75 +++ .../unittest/napi_js/mod_fs/mock/uv_fs_mock.h | 52 ++ 5 files changed, 706 insertions(+) create mode 100644 interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp create mode 100644 interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h create mode 100644 interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp create mode 100644 interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 2bc34018f..7357225ad 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -19,6 +19,7 @@ group("file_api_unittest") { "class_atomicfile:class_atomicfile_test", "class_file:class_file_test", "filemgmt_libn_test:filemgmt_libn_test", + "napi_js:napi_fs_test", "js:ani_file_environment_test", "js:ani_file_fs_mock_test", "js:ani_file_fs_test", diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp new file mode 100644 index 000000000..3c02cbcff --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp @@ -0,0 +1,477 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "libn_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptr LibnMock::libnMock = nullptr; +thread_local bool LibnMock::mockable = false; + +std::shared_ptr LibnMock::GetMock() +{ + if (libnMock == nullptr) { + libnMock = std::make_shared(); + } + return libnMock; +} + +void LibnMock::EnableMock() +{ + mockable = true; +} + +void LibnMock::DisableMock() +{ + libnMock = nullptr; + mockable = false; +} + +bool LibnMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +#ifdef __cplusplus +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +extern "C" { +napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->napi_unwrap(env, js_object, result); + } + + static napi_status (*realNapi)(napi_env, napi_value, void **) = []() { + auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_unwrap"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real napi_unwrap: " << dlerror(); + } + return func; + }(); + + if (!realNapi) { + return napi_ok; + } + + return realNapi(env, js_object, result); +} + +} // extern "C" + +bool NFuncArg::InitArgs(std::function argcChecker) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->InitArgs(argcChecker); + } + + static bool (*realInitArgs)(std::function) = []() { + auto func = (bool (*)(std::function))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argcChecker); +} + +bool NFuncArg::InitArgs(size_t argc) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->InitArgs(argc); + } + + static bool (*realInitArgs)(size_t) = []() { + auto func = (bool (*)(size_t))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(argc); +} + +bool NFuncArg::InitArgs(size_t minArgc, size_t maxArgc) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->InitArgs(minArgc, maxArgc); + } + + static bool (*realInitArgs)(size_t, size_t) = []() { + auto func = (bool (*)(size_t, size_t))dlsym(RTLD_NEXT, "InitArgs"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); + } + return func; + }(); + + if (!realInitArgs) { + return false; + } + + return realInitArgs(minArgc, maxArgc); +} + +size_t NFuncArg::GetArgc() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->GetArgc(); + } + + static size_t (*realGetArgc)() = []() { + auto func = (size_t (*)())dlsym(RTLD_NEXT, "GetArgc"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetArgc: " << dlerror(); + } + return func; + }(); + + if (!realGetArgc) { + return -1; + } + + return realGetArgc(); +} + +napi_value NFuncArg::GetThisVar() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->GetThisVar(); + } + + static napi_value (*realGetThisVar)() = []() { + auto func = (napi_value (*)())dlsym(RTLD_NEXT, "GetThisVar"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetThisVar: " << dlerror(); + } + return func; + }(); + + if (!realGetThisVar) { + return nullptr; + } + + return realGetThisVar(); +} + +napi_value NFuncArg::GetArg(size_t argPos) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->GetArg(argPos); + } + + static napi_value (*realGetArg)(size_t) = []() { + auto func = (napi_value (*)(size_t))dlsym(RTLD_NEXT, "GetArg"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real GetArg: " << dlerror(); + } + return func; + }(); + + if (!realGetArg) { + return nullptr; + } + + return realGetArg(argPos); +} + +void NError::ThrowErr(napi_env env) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErr(env); + } + + static void (*realThrowErr)(napi_env) = []() { + auto func = (void (*)(napi_env))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env); +} + +void NError::ThrowErr(napi_env env, int errCode) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErr(env, errCode); + } + + static void (*realThrowErr)(napi_env, int) = []() { + auto func = (void (*)(napi_env, int))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errCode); +} + +void NError::ThrowErr(napi_env env, std::string errMsg) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErr(env, errMsg); + } + + static void (*realThrowErr)(napi_env, std::string) = []() { + auto func = (void (*)(napi_env, std::string))dlsym(RTLD_NEXT, "ThrowErr"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errMsg); +} + +void NError::ThrowErrAddData(napi_env env, int errCode, napi_value data) +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ThrowErrAddData(env, errCode, data); + } + + static void (*realThrowErr)(napi_env, int, napi_value) = []() { + auto func = (void (*)(napi_env, int, napi_value))dlsym(RTLD_NEXT, "ThrowErrAddData"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErrAddData: " << dlerror(); + } + return func; + }(); + + if (!realThrowErr) { + return; + } + + return realThrowErr(env, errCode, data); +} + +std::tuple, size_t> NVal::ToUTF8String() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToUTF8String(); + } + + static std::tuple, size_t> (*realToUTF8String)() = []() { + auto func = (std::tuple, size_t> (*)())dlsym(RTLD_NEXT, "ToUTF8String"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToUTF8String: " << dlerror(); + } + return func; + }(); + + if (!realToUTF8String) { + return { false, nullptr, -1 }; + } + + return realToUTF8String(); +} + +std::tuple, size_t> NVal::ToUTF8String(std::string defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToUTF8String(defaultValue); + } + + static std::tuple, size_t> (*realToUTF8String)(std::string) = []() { + auto func = (std::tuple, size_t> (*)(std::string))dlsym(RTLD_NEXT, "ToUTF8String"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToUTF8String: " << dlerror(); + } + return func; + }(); + + if (!realToUTF8String) { + return { false, nullptr, -1 }; + } + + return realToUTF8String(defaultValue); +} + +std::tuple NVal::ToBool() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToBool(); + } + + static std::tuple (*realToBool)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToBool"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToBool: " << dlerror(); + } + return func; + }(); + + if (!realToBool) { + return { false, false }; + } + + return realToBool(); +} + +std::tuple NVal::ToBool(bool defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToBool(defaultValue); + } + + static std::tuple (*realToBool)(bool) = []() { + auto func = (std::tuple (*)(bool))dlsym(RTLD_NEXT, "ToBool"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToBool: " << dlerror(); + } + return func; + }(); + + if (!realToBool) { + return { false, false }; + } + + return realToBool(defaultValue); +} + +std::tuple NVal::ToInt32() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt32(); + } + + static std::tuple (*realToInt32)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToInt32"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt32: " << dlerror(); + } + return func; + }(); + + if (!realToInt32) { + return { false, 0 }; + } + + return realToInt32(); +} + +std::tuple NVal::ToInt32(int32_t defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt32(defaultValue); + } + + static std::tuple (*realToInt32)(int32_t) = []() { + auto func = (std::tuple (*)(int32_t))dlsym(RTLD_NEXT, "ToInt32"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt32: " << dlerror(); + } + return func; + }(); + + if (!realToInt32) { + return { false, 0 }; + } + + return realToInt32(defaultValue); +} + +std::tuple NVal::ToInt64() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt64(); + } + + static std::tuple (*realToInt64)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToInt64"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt64: " << dlerror(); + } + return func; + }(); + + if (!realToInt64) { + return { false, 0 }; + } + + return realToInt64(); +} + +std::tuple NVal::ToInt64(int64_t defaultValue) const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToInt64(defaultValue); + } + + static std::tuple (*realToInt64)(int64_t) = []() { + auto func = (std::tuple (*)(int64_t))dlsym(RTLD_NEXT, "ToInt64"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToInt64: " << dlerror(); + } + return func; + }(); + + if (!realToInt64) { + return { false, 0 }; + } + + return realToInt64(defaultValue); +} + +std::tuple NVal::ToDouble() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToDouble(); + } + + static std::tuple (*realToDouble)() = []() { + auto func = (std::tuple (*)())dlsym(RTLD_NEXT, "ToDouble"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToDouble: " << dlerror(); + } + return func; + }(); + + if (!realToDouble) { + return { false, 0 }; + } + + return realToDouble(); +} +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h new file mode 100644 index 000000000..098235ad0 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_MOCK_NAPI_MOCK_H +#define INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_MOCK_NAPI_MOCK_H + +#include "n_napi.h" +#include "filemgmt_libn.h" + +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; + +class ILibnMock { +public: + virtual ~ILibnMock() = default; + + // n_func_arg + virtual bool InitArgs(std::function argcChecker) = 0; + virtual bool InitArgs(size_t argc) = 0; + virtual bool InitArgs(size_t minArgc, size_t maxArgc) = 0; + virtual size_t GetArgc() = 0; + virtual napi_value GetArg(size_t argPos) = 0; + virtual napi_value GetThisVar() = 0; + + // n_class GetEntityOf + virtual napi_status napi_unwrap(napi_env env, napi_value js_object, void **result) = 0; + + // n_error + virtual void ThrowErr(napi_env env) = 0; + virtual void ThrowErr(napi_env env, int errCode) = 0; + virtual void ThrowErr(napi_env env, std::string errMsg) = 0; + virtual void ThrowErrAddData(napi_env env, int errCode, napi_value data) = 0; + + // n_val + virtual std::tuple, size_t> ToUTF8String() = 0; + virtual std::tuple, size_t> ToUTF8String(std::string defaultValue) = 0; + virtual std::tuple ToBool() = 0; + virtual std::tuple ToBool(bool defaultValue) = 0; + virtual std::tuple ToInt32() = 0; + virtual std::tuple ToInt32(int32_t defaultValue) = 0; + virtual std::tuple ToInt64() = 0; + virtual std::tuple ToInt64(int64_t defaultValue) = 0; + virtual std::tuple ToDouble() = 0; +}; + +class LibnMock : public ILibnMock { +public: + MOCK_METHOD(bool, InitArgs, (std::function), (override)); + MOCK_METHOD(bool, InitArgs, (size_t), (override)); + MOCK_METHOD(bool, InitArgs, (size_t, size_t), (override)); + MOCK_METHOD(size_t, GetArgc, (), (override)); + MOCK_METHOD(napi_value, GetArg, (size_t), (override)); + MOCK_METHOD(napi_value, GetThisVar, (), (override)); + + MOCK_METHOD(napi_status, napi_unwrap, (napi_env, napi_value, void **), (override)); + + MOCK_METHOD(void, ThrowErr, (napi_env), (override)); + MOCK_METHOD(void, ThrowErr, (napi_env, int), (override)); + MOCK_METHOD(void, ThrowErr, (napi_env, std::string), (override)); + MOCK_METHOD(void, ThrowErrAddData, (napi_env, int, napi_value), (override)); + + MOCK_METHOD((std::tuple, size_t>), ToUTF8String, (), (override)); + MOCK_METHOD((std::tuple, size_t>), ToUTF8String, (std::string), (override)); + MOCK_METHOD((std::tuple), ToBool, (), (override)); + MOCK_METHOD((std::tuple), ToBool, (bool), (override)); + MOCK_METHOD((std::tuple), ToInt32, (), (override)); + MOCK_METHOD((std::tuple), ToInt32, (int32_t), (override)); + MOCK_METHOD((std::tuple), ToInt64, (), (override)); + MOCK_METHOD((std::tuple), ToInt64, (int64_t), (override)); + MOCK_METHOD((std::tuple), ToDouble, (), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr libnMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_MOCK_NAPI_MOCK_H \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp new file mode 100644 index 000000000..727dc6e77 --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "uv_fs_mock.h" + +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace OHOS::FileManagement::ModuleFileIO; + +thread_local std::shared_ptr UvfsMock::uvfsMock = nullptr; +thread_local bool UvfsMock::mockable = false; + +std::shared_ptr UvfsMock::GetMock() +{ + if (uvfsMock == nullptr) { + uvfsMock = std::make_shared(); + } + return uvfsMock; +} + +void UvfsMock::EnableMock() +{ + mockable = true; +} + +void UvfsMock::DisableMock() +{ + uvfsMock = nullptr; + mockable = false; +} + +bool UvfsMock::IsMockable() +{ + return mockable; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test + +#ifdef __cplusplus +using namespace OHOS::FileManagement::ModuleFileIO::Test; + +int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) +{ + if (UvfsMock::IsMockable()) { + return UvfsMock::GetMock()->uv_fs_close(loop, req, file, cb); + } + + static int (*realUvFsClose)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb) = []() { + auto func = (int (*)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb))dlsym(RTLD_NEXT, "uv_fs_close"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real uv_fs_close: " << dlerror(); + } + return func; + }(); + + if (!realUvFsClose) { + return -1; + } + + return realUvFsClose(loop, req, file, cb); +} +#endif \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h new file mode 100644 index 000000000..2bf94892e --- /dev/null +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H +#define INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H + +#include "uv.h" +#include "filemgmt_libn.h" + +#include +#include + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace std::filesystem; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::LibN; + +class IUvfsMock { +public: + virtual ~IUvfsMock() = default; + virtual int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) = 0; +}; + +class UvfsMock : public IUvfsMock { +public: + MOCK_METHOD(int, uv_fs_close, (uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb), (override)); + +public: + static std::shared_ptr GetMock(); + static void EnableMock(); + static void DisableMock(); + static bool IsMockable(); + +private: + static thread_local std::shared_ptr uvfsMock; + static thread_local bool mockable; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::Test +#endif // INTERFACES_TEST_UNITTEST_NAPI_JS_MOD_FS_PROPERTIES_MOCK_UV_FS_MOCK_H \ No newline at end of file -- Gitee From 2c17d7b7f52f1ece94d9a8460087f39dc03117f4 Mon Sep 17 00:00:00 2001 From: wcj Date: Fri, 12 Sep 2025 11:51:59 +0800 Subject: [PATCH 5/5] propNExporter TDD Change-Id: I31b680bb637a54b6127a751a9bc7a90b4c4a2ab1 --- interfaces/test/unittest/BUILD.gn | 2 +- interfaces/test/unittest/napi_js/BUILD.gn | 7 +- .../unittest/napi_js/fdatasync_mock_test.cpp | 13 ++- .../unittest/napi_js/mock/fdatasync_mock.cpp | 84 ------------------- .../unittest/napi_js/mock/fdatasync_mock.h | 10 --- .../napi_js/mod_fs/mock/libn_mock.cpp | 21 +++++ .../unittest/napi_js/mod_fs/mock/libn_mock.h | 2 + .../napi_js/mod_fs/mock/uv_fs_mock.cpp | 43 ++++++++++ .../unittest/napi_js/mod_fs/mock/uv_fs_mock.h | 4 + .../napi_js/prop_n_exporter_mock_test.cpp | 44 +++++----- 10 files changed, 106 insertions(+), 124 deletions(-) diff --git a/interfaces/test/unittest/BUILD.gn b/interfaces/test/unittest/BUILD.gn index 7357225ad..928de28e3 100644 --- a/interfaces/test/unittest/BUILD.gn +++ b/interfaces/test/unittest/BUILD.gn @@ -19,7 +19,7 @@ group("file_api_unittest") { "class_atomicfile:class_atomicfile_test", "class_file:class_file_test", "filemgmt_libn_test:filemgmt_libn_test", - "napi_js:napi_fs_test", + "js:ani_file_environment_test", "js:ani_file_fs_mock_test", "js:ani_file_fs_test", diff --git a/interfaces/test/unittest/napi_js/BUILD.gn b/interfaces/test/unittest/napi_js/BUILD.gn index 44365231c..bf039cf3e 100644 --- a/interfaces/test/unittest/napi_js/BUILD.gn +++ b/interfaces/test/unittest/napi_js/BUILD.gn @@ -25,20 +25,23 @@ ohos_unittest("napi_file_fs_properties_test") { "${file_api_path}/interfaces/kits/js/src/common/file_helper", "${file_api_path}/interfaces/kits/js/src/mod_fs", "${file_api_path}/interfaces/kits/js/src/mod_fs/properties", + "${file_api_path}/interfaces/kits/native/task_signal", "${utils_path}/common/include", - "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock", "mock", + "mod_fs/mock", ] sources = [ "${file_api_path}/interfaces/kits/js/src/common/file_helper/fd_guard.cpp", "${file_api_path}/interfaces/kits/js/src/mod_fs/common_func.cpp", - "${file_api_path}/interfaces/test/unittest/js/mod_fs/properties/mock/uv_fs_mock.cpp", "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/fdatasync.cpp", + "${file_api_path}/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp", "mock/fdatasync_mock.cpp", "fdatasync_mock_test.cpp", "mock/prop_n_exporter_mock.cpp", "prop_n_exporter_mock_test.cpp", + "mod_fs/mock/libn_mock.cpp", + "mod_fs/mock/uv_fs_mock.cpp", ] deps = [ diff --git a/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp index 7966dac69..8ef6eefff 100644 --- a/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp +++ b/interfaces/test/unittest/napi_js/fdatasync_mock_test.cpp @@ -18,6 +18,7 @@ #include "fdatasync.h" #include "uv_fs_mock.h" #include "fdatasync_mock.h" +#include "libn_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; @@ -38,14 +39,12 @@ protected: void FdatasyncMockTest::SetUpTestCase(void) { uvMock = make_shared(); - Uvfs::ins = uvMock; FdatasyncMock::EnableMock(); GTEST_LOG_(INFO) << "SetUpTestCase"; } void FdatasyncMockTest::TearDownTestCase(void) { - Uvfs::ins = nullptr; uvMock = nullptr; FdatasyncMock::DisableMock(); GTEST_LOG_(INFO) << "TearDownTestCase"; @@ -70,7 +69,7 @@ void FdatasyncMockTest::TearDown(void) * @tc.level Level 1 */ -HWTEST_F(FdatasyncMockTest, FdatasyncMockTest_CloseSync_001, TestSize.Level1) +HWTEST_F(FdatasyncMockTest, FdatasyncMockTest_Sync_001, TestSize.Level1) { GTEST_LOG_(INFO) << "FdatasyncMockTest-begin FdatasyncMockTest_Sync_001"; napi_env env = reinterpret_cast(0x1000); @@ -78,12 +77,12 @@ HWTEST_F(FdatasyncMockTest, FdatasyncMockTest_CloseSync_001, TestSize.Level1) napi_callback_info mInfo = reinterpret_cast(0x1122); tuple tp = {true, 1}; - auto pMock = FdatasyncMock::GetMock(); - EXPECT_CALL(*pMock, InitArgs(_)).WillOnce(Return(true)); + auto pMock = LibnMock::GetMock(); + EXPECT_CALL(*pMock, InitArgs(A())).WillOnce(Return(true)); EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); EXPECT_CALL(*pMock, ToInt32()).WillOnce(Return(tp)); - EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(1)); - EXPECT_CALL(*pMock, ThrowErr(_, _)); + EXPECT_CALL(*uvMock, uv_fs_fdatasync(_, _, _, _)).WillOnce(Return(-1)); + EXPECT_CALL(*pMock, ThrowErr(_)); auto res = Fdatasync::Sync(env, mInfo); EXPECT_EQ(res, nullptr); diff --git a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp index d030adabc..21fd2e806 100644 --- a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp +++ b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.cpp @@ -52,69 +52,6 @@ bool FdatasyncMock::IsMockable() using namespace OHOS::FileManagement::ModuleFileIO::Test; -bool NFuncArg::InitArgs(std::function argcChecker) -{ - if (FdatasyncMock::IsMockable()) { - return FdatasyncMock::GetMock()->InitArgs(argcChecker); - } - - static bool (*realInitArgs)(std::function) = []() { - auto func = (bool(*)(std::function))dlsym(RTLD_NEXT, "InitArgs"); - if (!func) { - GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror(); - } - return func; - }(); - - if (!realInitArgs) { - return false; - } - - return realInitArgs(argcChecker); -} - -napi_value NFuncArg::GetArg(size_t argPos) const -{ - if (FdatasyncMock::IsMockable()) { - return FdatasyncMock::GetMock()->GetArg(argPos); - } - - static napi_value (*realGetArg)(size_t) = []() { - auto func = (napi_value(*)(size_t))dlsym(RTLD_NEXT, "GetArg"); - if (!func) { - GTEST_LOG_(ERROR) << "Failed to resolve real GetArg: " << dlerror(); - } - return func; - }(); - - if (!realGetArg) { - return nullptr; - } - - return realGetArg(argPos); -} - -tuple NVal::ToInt32() const -{ - if (FdatasyncMock::IsMockable()) { - return FdatasyncMock::GetMock()->ToInt32(); - } - - static tuple (*realToInt32)() = []() { - auto func = (tuple(*)())dlsym(RTLD_NEXT, "ToInt32"); - if (!func) { - GTEST_LOG_(ERROR) << "Failed to resolve real ToInt32: " << dlerror(); - } - return func; - }(); - - if (!realToInt32) { - return {false, 0}; - } - - return realToInt32(); -} - NVal NVal::CreateUndefined(napi_env env) { if (FdatasyncMock::IsMockable()) { @@ -135,24 +72,3 @@ NVal NVal::CreateUndefined(napi_env env) return realCreateUndefined(env); } - -void NError::ThrowErr(napi_env env, std::string errMsg) -{ - if (FdatasyncMock::IsMockable()) { - return FdatasyncMock::GetMock()->ThrowErr(env, errMsg); - } - - static void (*realThrowErr)(napi_env, std::string) = []() { - auto func = (void (*)(napi_env, std::string))dlsym(RTLD_NEXT, "ThrowErr"); - if (!func) { - GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror(); - } - return func; - }(); - - if (!realThrowErr) { - return; - } - - return realThrowErr(env, errMsg); -} \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h index 368a8fe41..87a355df3 100644 --- a/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h +++ b/interfaces/test/unittest/napi_js/mock/fdatasync_mock.h @@ -33,22 +33,12 @@ using std::tuple; class IFdatasyncMock { public: virtual ~IFdatasyncMock() = default; - virtual bool InitArgs(std::function argcChecker) = 0; - virtual napi_value GetThisVar() = 0; virtual NVal CreateUndefined(napi_env env) = 0; - virtual napi_value GetArg(size_t argPos) = 0; - virtual tuple ToInt32() = 0; - virtual void ThrowErr(napi_env env, std::string errMsg) = 0; }; class FdatasyncMock : public IFdatasyncMock { public: -MOCK_METHOD(bool, InitArgs, (std::function), (override)); -MOCK_METHOD(napi_value, GetThisVar, (), (override)); MOCK_METHOD(NVal, CreateUndefined, (napi_env), (override)); -MOCK_METHOD(napi_value, GetArg, (size_t), (override)); -MOCK_METHOD((tuple), ToInt32, (), (override)); -MOCK_METHOD(void, ThrowErr, (napi_env, std::string), (override)); public: static std::shared_ptr GetMock(); diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp index 3c02cbcff..2f8dd42c5 100644 --- a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.cpp @@ -474,4 +474,25 @@ std::tuple NVal::ToDouble() const return realToDouble(); } + +std::tuple, size_t> NVal::ToUTF8StringPath() const +{ + if (LibnMock::IsMockable()) { + return LibnMock::GetMock()->ToUTF8StringPath(); + } + + static std::tuple, size_t> (*realToUTF8StringPath)() = []() { + auto func = (std::tuple, size_t> (*)())dlsym(RTLD_NEXT, "ToUTF8StringPath"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real ToUTF8StringPath: " << dlerror(); + } + return func; + }(); + + if (!realToUTF8StringPath) { + return { false, nullptr, -1 }; + } + + return realToUTF8StringPath(); +} #endif \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h index 098235ad0..082a27943 100644 --- a/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/libn_mock.h @@ -50,6 +50,7 @@ public: // n_val virtual std::tuple, size_t> ToUTF8String() = 0; + virtual std::tuple, size_t> ToUTF8StringPath() = 0; virtual std::tuple, size_t> ToUTF8String(std::string defaultValue) = 0; virtual std::tuple ToBool() = 0; virtual std::tuple ToBool(bool defaultValue) = 0; @@ -77,6 +78,7 @@ public: MOCK_METHOD(void, ThrowErrAddData, (napi_env, int, napi_value), (override)); MOCK_METHOD((std::tuple, size_t>), ToUTF8String, (), (override)); + MOCK_METHOD((std::tuple, size_t>), ToUTF8StringPath, (), (override)); MOCK_METHOD((std::tuple, size_t>), ToUTF8String, (std::string), (override)); MOCK_METHOD((std::tuple), ToBool, (), (override)); MOCK_METHOD((std::tuple), ToBool, (bool), (override)); diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp index 727dc6e77..7e8f9c8ee 100644 --- a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.cpp @@ -72,4 +72,47 @@ int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) return realUvFsClose(loop, req, file, cb); } + +int uv_fs_fdatasync(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) +{ + if (UvfsMock::IsMockable()) { + return UvfsMock::GetMock()->uv_fs_fdatasync(loop, req, file, cb); + } + + static int (*realUvFsfdatasync)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb) = []() { + auto func = (int (*)(uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb))dlsym(RTLD_NEXT, "uv_fs_fdatasync"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real uv_fs_fdatasync: " << dlerror(); + } + return func; + }(); + + if (!realUvFsfdatasync) { + return -1; + } + + return realUvFsfdatasync(loop, req, file, cb); +} + +int uv_fs_unlink(uv_loop_t *loop, uv_fs_t *req, const char * file, uv_fs_cb cb) +{ + if (UvfsMock::IsMockable()) { + return UvfsMock::GetMock()->uv_fs_unlink(loop, req, file, cb); + } + + static int (*realUvFsUnlink)(uv_loop_t *, uv_fs_t *, const char *, uv_fs_cb) = []() { + auto func = (int (*)(uv_loop_t *, uv_fs_t *, const char *, uv_fs_cb))dlsym(RTLD_NEXT, "uv_fs_unlink"); + if (!func) { + GTEST_LOG_(ERROR) << "Failed to resolve real uv_fs_unlink: " << dlerror(); + } + return func; + }(); + + if (!realUvFsUnlink) { + return -1; + } + + return realUvFsUnlink(loop, req, file, cb); +} + #endif \ No newline at end of file diff --git a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h index 2bf94892e..778012c36 100644 --- a/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h +++ b/interfaces/test/unittest/napi_js/mod_fs/mock/uv_fs_mock.h @@ -31,11 +31,15 @@ class IUvfsMock { public: virtual ~IUvfsMock() = default; virtual int uv_fs_close(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) = 0; + virtual int uv_fs_fdatasync(uv_loop_t *loop, uv_fs_t *req, uv_file file, uv_fs_cb cb) = 0; + virtual int uv_fs_unlink(uv_loop_t *loop, uv_fs_t *req, const char *path, uv_fs_cb cb) = 0; }; class UvfsMock : public IUvfsMock { public: MOCK_METHOD(int, uv_fs_close, (uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb), (override)); + MOCK_METHOD(int, uv_fs_fdatasync, (uv_loop_t *, uv_fs_t *, uv_file, uv_fs_cb), (override)); + MOCK_METHOD(int, uv_fs_unlink, (uv_loop_t *, uv_fs_t *, const char *, uv_fs_cb), (override)); public: static std::shared_ptr GetMock(); diff --git a/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp b/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp index 2a0de8b4f..c4f57284d 100644 --- a/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp +++ b/interfaces/test/unittest/napi_js/prop_n_exporter_mock_test.cpp @@ -12,12 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include +#include +#include #include #include #include "prop_n_exporter_mock.h" #include "uv_fs_mock.h" #include "prop_n_exporter.h" +#include "libn_mock.h" namespace OHOS::FileManagement::ModuleFileIO::Test { using namespace testing; @@ -38,14 +41,12 @@ protected: void PropNExporterMockTest::SetUpTestCase(void) { uvMock = make_shared(); - Uvfs::ins = uvMock; PropNExporterMock::EnableMock(); GTEST_LOG_(INFO) << "SetUpTestCase"; } void PropNExporterMockTest::TearDownTestCase(void) { - Uvfs::ins = nullptr; uvMock = nullptr; PropNExporterMock::DisableMock(); GTEST_LOG_(INFO) << "TearDownTestCase"; @@ -63,32 +64,35 @@ void PropNExporterMockTest::TearDown(void) } /** - * @tc.name: PropNExporterMockTest_Sync_001 - * @tc.desc: Test function of Sync() interface for failed. + * @tc.name: PropNExporterMockTest_UnlinkSync_001 + * @tc.desc: Test function of UnlinkSync() interface for failed. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(PropNExporterMockTest, PropNExporterMockTest_CloseSync_001, TestSize.Level1) +HWTEST_F(PropNExporterMockTest, PropNExporterMockTest_UnlinkSync_001, TestSize.Level1) { - GTEST_LOG_(INFO) << "PropNExporterMockTest-begin PropNExporterMockTest_Sync_001"; - // napi_env env = reinterpret_cast(0x1000); - // napi_value nv = reinterpret_cast(0x1200); - // napi_callback_info mInfo = reinterpret_cast(0x1122); - // tuple tp = {true, 1}; + GTEST_LOG_(INFO) << "PropNExporterMockTest-begin PropNExporterMockTest_UnlinkSync_001"; + napi_env env = reinterpret_cast(0x1000); + napi_value nv = reinterpret_cast(0x1200); + napi_callback_info mInfo = reinterpret_cast(0x1122); + + size_t strLen = 10; + auto strPtr = make_unique(strLen); + tuple, size_t> tp = { true, move(strPtr), 10 }; - // auto pMock = PropNExporterMock::GetMock(); - // EXPECT_CALL(*pMock, InitArgs(_)).WillOnce(Return(true)); - // EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); - // EXPECT_CALL(*pMock, ToInt32()).WillOnce(Return(tp)); - // EXPECT_CALL(*uvMock, uv_fs_PropNExporter(_, _, _, _)).WillOnce(Return(1)); - // EXPECT_CALL(*pMock, ThrowErr(_, _)); + auto pMock = LibnMock::GetMock(); + EXPECT_CALL(*pMock, InitArgs(A())).WillOnce(Return(true)); + EXPECT_CALL(*pMock, GetArg(_)).WillOnce(Return(nv)); + EXPECT_CALL(*pMock, ToUTF8StringPath()).WillOnce(Return(move(tp))); + EXPECT_CALL(*uvMock, uv_fs_unlink(_, _, _, _)).WillOnce(Return(-1)); + EXPECT_CALL(*pMock, ThrowErr(_)); - // auto res = PropNExporter::Sync(env, mInfo); - // EXPECT_EQ(res, nullptr); + auto res = PropNExporter::UnlinkSync(env, mInfo); + EXPECT_EQ(res, nullptr); - GTEST_LOG_(INFO) << "PropNExporterMockTest-end PropNExporterMockTest_Sync_001"; + GTEST_LOG_(INFO) << "PropNExporterMockTest-end PropNExporterMockTest_UnlinkSync_001"; } } \ No newline at end of file -- Gitee