TypeError [ERR_INVALID_ARG_TYPE]:“路径”参数必须为字符串类型。收到对象的实例

时间:2020-05-28 15:06:52

标签: javascript node.js firebase google-cloud-firestore jestjs

我正在使用安全规则source code中的tutorial来尝试与Jest进行集成测试,以用于我的Javascript异步功能async_create_post,该功能用于我的Firebase HTTP函数{{1} }所涉及的文件具有以下目录结构:

测试文件:create_post

要测试的文件:root/tests/handlers/posts.test.js

教程中的帮助程序代码:root/functions/handlers/posts.js

这是涉及的源代码:

posts.test.js

root/tests/rules/helpers.js

posts.js

const { setup, teardown} = require("../rules/helpers");
const {
  async_get_all_undeleted_posts,
  async_get_post,
  async_delete_post,
  async_create_post
} = require("../../functions/handlers/posts");


describe("Post Creation", () => {
  afterEach(async () => {
    await teardown();
  });

  test("should create a post", async () => {

    const db = await setup();


    const malloryUID = "non-existent uid";
    const firstPost = {
      body: "First post from Mallory",
      author_id: malloryUID,
      images: ["url1", "url2"]
    }

    const before_post_snapshot = await db.collection("posts").get();
    expect(before_post_snapshot.docs.length).toBe(0);


    await async_create_post(firstPost); //fails at this point, expected to create a new post, but instead threw an error
    const after_post_snapshot = await db.collection("posts").get();
    expect(after_post_snapshot.docs.length).toBe(1);
  });

});

当我在1个终端运行const {admin, db } = require('../util/admin'); //admin.initializeApp(config); //my credentials //const db = admin.firestore(); const { uuid } = require("uuidv4"); const { success_response, error_response } = require("../util/validators"); exports.async_create_post = async (data, context) => { try { const images = []; data.images.forEach((url) => { images.push({ uid: uuid(), url: url }); }) const postRecord = { body: data.body, images: images, last_updated: admin.firestore.FieldValue.serverTimestamp(), like_count: 0, comment_count: 0, deleted: false, author_id: data.author_id }; const generatedToken = uuid(); await db .collection("posts") .doc(generatedToken) .set(postRecord); // return success_response(); return success_response(generatedToken); } catch (error) { console.log("Error in creation of post", error); return error_response(error); } } 的Webstorm IDE中运行测试时,收到以下错误消息。

Firebase emulators:start

console.log Error in creation of post TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of Object at validateString (internal/validators.js:120:11) at Object.basename (path.js:1156:5) at GrpcClient.loadProto (/Users/isaac/Desktop/project/functions/node_modules/google-gax/src/grpc.ts:166:23) at new FirestoreClient (/Users/isaac/Desktop/project/functions/node_modules/@google-cloud/firestore/build/src/v1/firestore_client.js:118:38) at ClientPool.clientFactory (/Users/isaac/Desktop/project/functions/node_modules/@google-cloud/firestore/build/src/index.js:330:26) at ClientPool.acquire (/Users/isaac/Desktop/project/functions/node_modules/@google-cloud/firestore/build/src/pool.js:87:35) at ClientPool.run (/Users/isaac/Desktop/project/functions/node_modules/@google-cloud/firestore/build/src/pool.js:164:29) at Firestore.request (/Users/isaac/Desktop/project/functions/node_modules/@google-cloud/firestore/build/src/index.js:961:33) at WriteBatch.commit_ (/Users/isaac/Desktop/project/functions/node_modules/@google-cloud/firestore/build/src/write-batch.js:485:48) at exports.async_create_post (/Users/isaac/Desktop/project/functions/handlers/posts.js:36:5) { code: 'ERR_INVALID_ARG_TYPE' } at exports.async_create_post (/Users/isaac/Desktop/project/functions/handlers/posts.js:44:13) Error: expect(received).toBe(expected) // Object.is equality Expected: 1 Received: 0 <Click to see difference> at Object.<anonymous> (/Users/isaac/Desktop/project/tests/handlers/posts.test.js:59:45) 来自Error in creation of post中的console.log("Error in creation of post", error);,因此该帖子的标题中显示了错误。

我想知道为什么从posts.js调用async_create_post会导致此错误,并且没有按预期行为用其他记录填充数据库。如果需要更多信息来解决问题,请告知我。

有些代码段可能会提供更多上下文。

helpers.js [从存储库复制]

posts.test.js

index.js

const firebase = require("@firebase/testing");
const fs = require("fs");

module.exports.setup = async (auth, data) => {
  const projectId = `rules-spec-${Date.now()}`;

  const app = firebase.initializeTestApp({
    projectId,
    auth
  });

  const db = app.firestore();

  // Apply the test rules so we can write documents
  await firebase.loadFirestoreRules({
    projectId,
    rules: fs.readFileSync("firestore-test.rules", "utf8")
  });

  // write mock documents if any
  if (data) {
    for (const key in data) {
      const ref = db.doc(key); // This means the key should point directly to a document
      await ref.set(data[key]);
    }
  }

  // Apply the actual rules for the project
  await firebase.loadFirestoreRules({
    projectId,
    rules: fs.readFileSync("firestore.rules", "utf8")
  });

  return db;
  // return firebase;
};

module.exports.teardown = async () => {
  // Delete all apps currently running in the firebase simulated environment
  Promise.all(firebase.apps().map(app => app.delete()));
};

// Add extensions onto the expect method
expect.extend({
  async toAllow(testPromise) {
    let pass = false;
    try {
      await firebase.assertSucceeds(testPromise);
      pass = true;
    } catch (error) {
      // log error to see which rules caused the test to fail
      console.log(error);
    }

    return {
      pass,
      message: () =>
        "Expected Firebase operation to be allowed, but it was denied"
    };
  }
});

expect.extend({
  async toDeny(testPromise) {
    let pass = false;
    try {
      await firebase.assertFails(testPromise);
      pass = true;
    } catch (error) {
      // log error to see which rules caused the test to fail
      console.log(error);
    }

    return {
      pass,
      message: () =>
        "Expected Firebase operation to be denied, but it was allowed"
    };
  }
});

1 个答案:

答案 0 :(得分:0)

该错误消息意味着 path 模块的方法(如 path.join)期望其参数之一是字符串,但得到了其他参数。

我通过二进制搜索对程序进行了注释,直到错误消失,我发现了有问题的行。

也许您的模块之一使用了 path 并且您提供了错误的参数。