I inherited our current codebase with existing server-only unit tests that look nothing like the examples in the Meteor guide. Does anyone else roll their tests this way (see below for details)?
We have found these tests to be very effective and have not even considered investing in any full stack or client-side tests (maybe a happy flow some day). The tests include utility method testing from the /imports and /server directories but most importantly test our internal APIs (many meteor methods and a few publications).
Here’s the general pattern for a test. It connects the test code to the running instance, assigns a user id to the connection instead of logging in and invokes some methods that are supposed to return something or mutate the database in a way that can be inspected using other meteor methods or in some cases by reviewing mongodb collection contents directly.
import "some file that ensures that all method registrations are set up along with collection instances"
// Create a connection to the server and
// associates the connection with user with {{ userId }}.
// This enables "logged in" method calls.
export function withUser(userId: string) {
if (!Meteor.isTest) {
throw new Meteor.Error("Only available in unit tests");
}
const connection = DDP.connect(Meteor.absoluteUrl());
connection.call("setUserId", userId);
return connection;
}
describe("Top level thing", () => {
let conn: DDP.DDPStatic;
before(() => {
resetDatabase(); // from "meteor/xolvio:cleaner"
const userId = (code that creates a user, using the Accounts package)
conn = withUser(userId);
});
after(() => {
conn.disconnect();
});
it("should test something", () => {
const result = conn.call("my_method", ...methodparameters);
expect(result).to.be.something;
});
As I say, this pattern was not my invention but we use it with great success and would recommend it to anyone that builds apps in the same style we do (focusing on isolation between server and client by using well defined API methods, not implicit shared collections and whatnot).