Loading...
Loading...
Use when setting up, designing, writing, or repairing tests and test harnesses in a Meteor 3 app. Triggers on meteortesting:mocha, --driver-package, TEST_WATCH, TEST_BROWSER_DRIVER, MOCHA_GREP, meteor.testModule, focused tests, .only, Meteor.server.method_handlers, Meteor.server.publish_handlers, DDP.connect, --full-app integration mode, sinon, async test signatures, Playwright/Cypress E2E. Use this skill when the user asks about test runners, asks about testing publications, or asks about Jest vs Mocha in Meteor. For a failing, hanging, or flaky test whose failing layer or root cause is unknown, use meteor-debugging before changing the test or app.
npx skill4agent add meteor/agent-skills meteor-testingmeteortesting:mochameteor-debuggingmeteor-debuggingmeteortesting:mochaMeteor.server.method_handlers[name].apply(ctx, args)publish_handlers--full-appDDP.connectmeteor test --full-appmeteor add meteortesting:mocha
meteor npm install --save-dev @types/mocha// package.json
{
"scripts": {
"test": "TEST_WATCH=1 meteor test --driver-package meteortesting:mocha",
"test:ci": "meteor test --once --driver-package meteortesting:mocha",
"test:full": "meteor test --full-app --driver-package meteortesting:mocha"
}
}*.test[s].**.spec[s].*tests/meteor.testModule--full-app*.app-test[s].**.app-spec[s].*Meteor.isAppTestMOCHA_GREP.meteor/versions.onlymeteor.testModulereferences/focused-runs.mdimport assert from "node:assert/strict";
import { Meteor } from "meteor/meteor";
import { Items } from "/imports/api/items";
if (Meteor.isServer) {
describe("items.add", function () {
beforeEach(async function () {
await Items.removeAsync({});
});
it("inserts when authed", async function () {
const _id = await Meteor.server.method_handlers["items.add"].apply(
{ userId: "u1" },
[{ title: "x", qty: 1 }],
);
const doc = await Items.findOneAsync(_id);
assert.equal(doc.title, "x");
});
it("rejects when unauthed", async function () {
await assert.rejects(() =>
Meteor.server.method_handlers["items.add"].apply({ userId: null }, [{}]),
);
});
});
}.apply(context, argsArray)Meteor.server.method_handlers[name]thisuserIdunblockconnectionif (Meteor.isServer) {
describe("items.mine publication", function () {
it("only ships the subscribing user's items", async function () {
await Items.removeAsync({});
await Items.insertAsync({ _id: "a", ownerId: "u1" });
await Items.insertAsync({ _id: "b", ownerId: "u2" });
const cursor = await Meteor.server.publish_handlers["items.mine"]
.apply({ userId: "u1" }, []);
const docs = await cursor.fetchAsync();
assert.deepEqual(docs.map((d) => d._id), ["a"]);
});
});
}this.addedthis.changed--full-app--full-appimport { DDP } from "meteor/ddp-client";
import { Mongo } from "meteor/mongo";
import { Tracker } from "meteor/tracker";
const conn = DDP.connect(Meteor.absoluteUrl());
const RemoteItems = new Mongo.Collection("items", { connection: conn });
function ready(sub) {
return new Promise((resolve) => {
const computation = Tracker.autorun((c) => {
if (sub.ready()) {
c.stop();
resolve();
}
});
});
}
const sub = conn.subscribe("items.mine");
await ready(sub);
const docs = RemoteItems.find().fetch();meteor test --full-app --driver-package meteortesting:mochaif (Meteor.isClient) {
describe("Items minimongo", function () {
beforeEach(function () { Items.remove({}); });
it("filters by ownerId", function () {
Items.insert({ _id: "a", ownerId: "u1" });
Items.insert({ _id: "b", ownerId: "u2" });
assert.equal(Items.find({ ownerId: "u1" }).count(), 1);
});
});
}TEST_BROWSER_DRIVER=puppeteerTEST_BROWSER_DRIVERmeteortesting:mochaif (Meteor.isServer) { ... }beforeEachbeforeEachMeteor.ErrorMeteor.userIdafterEachMeteor.callMeteor.callAsyncmethod_handlersreferences/mocha-setup.mdreferences/focused-runs.mdreferences/ddp-test-helpers.mdreferences/eval-cases.md