@bernierllc/vitest-email-testing
v1.2.0
Published
Vitest plugin and matchers for modern email testing with TypeScript support, concurrent testing, and async assertions
Readme
@bernierllc/vitest-email-testing
Vitest plugin and matchers for modern email testing with TypeScript support, concurrent testing, and async assertions.
Features
- 🎯 Custom Vitest Matchers - Email-specific assertion matchers
- ⚡ Fast Test Execution - Optimized for Vitest's speed
- 🔄 Concurrent Testing - Safe parallel test execution
- 📝 TypeScript Support - Full type safety
- 🌐 ES Module Support - Native ESM compatibility
- 🧪 Async Assertions - Promise-based email testing
Installation
npm install --save-dev @bernierllc/vitest-email-testingQuick Start
Configure Vitest
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { emailTesting } from '@bernierllc/vitest-email-testing';
export default defineConfig({
plugins: [
emailTesting({
smtp: {
port: 2525,
host: 'localhost'
}
})
],
test: {
globals: true
}
});Write Tests
import { describe, test, expect } from 'vitest';
describe('Email Tests', () => {
test('welcome email', async () => {
const email = emailTesting.createTestData({
subject: 'Welcome!',
html: '<p>Welcome to our service</p>'
});
expect(email).toHaveEmailSubject(/Welcome/);
expect(email).toHaveHtmlContent('our service');
});
});Custom Matchers
Basic Email Assertions
expect(email).toHaveEmailRecipient('[email protected]');
expect(email).toHaveEmailSender('[email protected]');
expect(email).toHaveEmailSubject('Welcome');
expect(email).toHaveEmailSubject(/Welcome/); // Regex supportContent Assertions
expect(email).toHaveEmailContent('Hello World');
expect(email).toHaveHtmlContent('<p>Hello</p>');
expect(email).toHaveTextContent('Plain text');Template Assertions
expect(email).toHaveCompletedTemplate();
expect(email).toHaveTemplateVariable('userName', 'John Doe');
expect(email).toNotHaveUnreplacedVariables();Compliance Assertions
expect(email).toBeCompliantEmail('US');
expect(email).toHaveUnsubscribeLink();
expect(email).toHavePhysicalAddress();Async Assertions
await expect(email).toHaveBeenDelivered();
await expect(email).toHaveBeenDeliveredWithin(5000);Schema Validation
const schema = {
type: 'object',
properties: {},
required: ['from', 'to', 'subject']
};
expect(email).toSatisfyEmailSchema(schema);Test Utilities
Generate Test Emails
import { generateTestEmail, generateCompliantEmail } from '@bernierllc/vitest-email-testing';
// Basic test email
const email = generateTestEmail({
from: '[email protected]',
subject: 'Custom Subject'
});
// Compliant email
const compliantEmail = generateCompliantEmail('US');Email Sender Mocking
import { createEmailSenderMock } from '@bernierllc/vitest-email-testing';
const mock = createEmailSenderMock();
mock.mockSendSuccess({ delay: 100 });
// Test your code
await sendEmail('[email protected]');
// Verify
expect(mock.send.calls).toHaveLength(1);Batch Testing
import { batchSendEmails } from '@bernierllc/vitest-email-testing';
const emails = await batchSendEmails(100, (index) =>
generateTestEmail({ to: `user${index}@example.com` })
);Concurrent Testing
describe.concurrent('Email Performance', () => {
test('send 100 emails', async () => {
const emails = await batchSendEmails(100, (i) =>
generateTestEmail({ to: `user${i}@example.com` })
);
expect(emails).toHaveLength(100);
});
});Configuration Options
emailTesting({
smtp: {
port: 2525,
host: 'localhost'
},
environment: {
isolation: 'per-test',
cleanup: 'auto',
timeout: 30000
},
vitest: {
concurrent: true,
globalSetup: true,
snapshotFormat: 'email-optimized'
},
watchTemplates: {
enabled: true,
patterns: ['templates/**/*.html'],
rerunTests: true
}
})API Reference
Types
EmailData- Email data structureEmailMatcher- Email matching criteriaEmailSchema- Email validation schemaComplianceRegion- Compliance region typeEmailTestingConfig- Plugin configuration
Functions
emailTesting(config?)- Vitest plugininstallEmailMatchers()- Install custom matcherscreateEmailSenderMock(sender?)- Create email sender mockgenerateTestEmail(overrides?)- Generate test emailgenerateCompliantEmail(region?)- Generate compliant emailwaitForCondition(condition, options?)- Wait for condition
Integration Documentation
Integration Status
Logger: Not applicable (testing utility) NeverHub: Not applicable (testing utility)
This package is a testing utility and does not require runtime integrations with @bernierllc/logger or @bernierllc/neverhub-adapter. It is designed to be a standalone testing tool that works independently of application infrastructure.
Usage with Other @bernierllc Packages
This package can be used to test email functionality in any @bernierllc service package:
// Testing @bernierllc/email-service
import { describe, test, expect } from 'vitest';
import { EmailService } from '@bernierllc/email-service';
import { createEmailSenderMock } from '@bernierllc/vitest-email-testing';
describe('EmailService', () => {
test('sends welcome email', async () => {
const mock = createEmailSenderMock();
const service = new EmailService({ sender: mock });
await service.sendWelcome('[email protected]');
expect(mock.send.calls[0]).toHaveEmailSubject('Welcome');
});
});Graceful Degradation
As a testing utility, this package operates independently and does not depend on external services. All functionality is self-contained within the test environment.
License
Copyright (c) 2025 Bernier LLC. See LICENSE.md for details.
