Vitest plugin and matchers for modern email testing with TypeScript support, concurrent testing, and async assertions
npm install @bernierllc/vitest-email-testingVitest plugin and matchers for modern email testing with TypeScript support, concurrent testing, and async assertions.
- ๐ฏ 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
``bash`
npm install --save-dev @bernierllc/vitest-email-testing
`typescript
// 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
}
});
`
`typescript
import { describe, test, expect } from 'vitest';
describe('Email Tests', () => {
test('welcome email', async () => {
const email = emailTesting.createTestData({
subject: 'Welcome!',
html: '
Welcome to our service
' expect(email).toHaveEmailSubject(/Welcome/);
expect(email).toHaveHtmlContent('our service');
});
});
`
`typescript`
expect(email).toHaveEmailRecipient('user@example.com');
expect(email).toHaveEmailSender('noreply@example.com');
expect(email).toHaveEmailSubject('Welcome');
expect(email).toHaveEmailSubject(/Welcome/); // Regex support
` Hellotypescript`
expect(email).toHaveEmailContent('Hello World');
expect(email).toHaveHtmlContent('
expect(email).toHaveTextContent('Plain text');
`typescript`
expect(email).toHaveCompletedTemplate();
expect(email).toHaveTemplateVariable('userName', 'John Doe');
expect(email).toNotHaveUnreplacedVariables();
`typescript`
expect(email).toBeCompliantEmail('US');
expect(email).toHaveUnsubscribeLink();
expect(email).toHavePhysicalAddress();
`typescript`
await expect(email).toHaveBeenDelivered();
await expect(email).toHaveBeenDeliveredWithin(5000);
`typescript
const schema = {
type: 'object',
properties: {},
required: ['from', 'to', 'subject']
};
expect(email).toSatisfyEmailSchema(schema);
`
`typescript
import { generateTestEmail, generateCompliantEmail } from '@bernierllc/vitest-email-testing';
// Basic test email
const email = generateTestEmail({
from: 'sender@example.com',
subject: 'Custom Subject'
});
// Compliant email
const compliantEmail = generateCompliantEmail('US');
`
`typescript
import { createEmailSenderMock } from '@bernierllc/vitest-email-testing';
const mock = createEmailSenderMock();
mock.mockSendSuccess({ delay: 100 });
// Test your code
await sendEmail('user@example.com');
// Verify
expect(mock.send.calls).toHaveLength(1);
`
`typescript
import { batchSendEmails } from '@bernierllc/vitest-email-testing';
const emails = await batchSendEmails(100, (index) =>
generateTestEmail({ to: user${index}@example.com })`
);
`typescriptuser${i}@example.com
describe.concurrent('Email Performance', () => {
test('send 100 emails', async () => {
const emails = await batchSendEmails(100, (i) =>
generateTestEmail({ to: })
);
expect(emails).toHaveLength(100);
});
});
`
`typescript`
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
}
})
- EmailData - Email data structureEmailMatcher
- - Email matching criteriaEmailSchema
- - Email validation schemaComplianceRegion
- - Compliance region typeEmailTestingConfig
- - Plugin configuration
- 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
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.
This package can be used to test email functionality in any @bernierllc service package:
`typescript
// 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('user@example.com');
expect(mock.send.calls[0]).toHaveEmailSubject('Welcome');
});
});
``
As a testing utility, this package operates independently and does not depend on external services. All functionality is self-contained within the test environment.
Copyright (c) 2025 Bernier LLC. See LICENSE.md for details.