or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-compilation.mdcollections-utilities.mdconfig-data.mdcore-language.mddependency-management.mdindex.mdio-file-processing.mdjson-processing.mdsql-database.mdtemplate-engines.mdtesting-apis.mdtime-date.mdtransform-annotations.mdxml-processing.md

testing-apis.mddocs/

0

# Testing APIs

1

2

Comprehensive testing framework with enhanced JUnit integration, mocking capabilities, and Groovy-specific assertion utilities. Provides GroovyTestCase for improved test organization and mock objects for isolation testing.

3

4

## Capabilities

5

6

### GroovyTestCase Framework

7

8

Enhanced test case base class that extends JUnit with Groovy-specific testing features and improved assertion methods.

9

10

```java { .api }

11

/**

12

* Enhanced test case class with Groovy-specific testing utilities

13

*/

14

abstract class GroovyTestCase extends TestCase {

15

/**

16

* Create test case with name

17

*/

18

GroovyTestCase();

19

GroovyTestCase(String name);

20

21

/**

22

* Assert that code execution throws expected exception

23

*/

24

void shouldFail(Closure code);

25

void shouldFail(Class<? extends Throwable> expectedType, Closure code);

26

void shouldFail(String expectedMessage, Closure code);

27

28

/**

29

* Assert that code executes without throwing exception

30

*/

31

void shouldNotFail(Closure code);

32

33

/**

34

* Assert equality with Groovy-aware comparison

35

*/

36

void assertEquals(Object expected, Object actual);

37

void assertEquals(String message, Object expected, Object actual);

38

39

/**

40

* Assert collection contents regardless of order

41

*/

42

void assertArrayEquals(Object[] expected, Object[] actual);

43

void assertCollectionEquals(Collection expected, Collection actual);

44

45

/**

46

* Assert script compilation and execution

47

*/

48

void assertScript(String script);

49

void assertScript(String script, Object expectedResult);

50

51

/**

52

* Get GroovyShell for script testing

53

*/

54

GroovyShell getShell();

55

56

/**

57

* Execute Groovy script in test context

58

*/

59

Object evaluate(String script);

60

}

61

```

62

63

**Usage Examples:**

64

65

```groovy

66

import groovy.test.GroovyTestCase

67

68

class MathUtilsTest extends GroovyTestCase {

69

70

void testBasicArithmetic() {

71

def calculator = new Calculator()

72

73

assertEquals(5, calculator.add(2, 3))

74

assertEquals(6, calculator.multiply(2, 3))

75

assertEquals(2.5, calculator.divide(5, 2))

76

}

77

78

void testDivisionByZero() {

79

def calculator = new Calculator()

80

81

shouldFail(ArithmeticException) {

82

calculator.divide(10, 0)

83

}

84

85

shouldFail("Division by zero") {

86

calculator.safeDivide(10, 0)

87

}

88

}

89

90

void testCollectionOperations() {

91

def list1 = [1, 2, 3]

92

def list2 = [3, 1, 2] // Different order

93

94

assertCollectionEquals(list1, list2) // Order doesn't matter

95

96

def array1 = [1, 2, 3] as int[]

97

def array2 = [1, 2, 3] as int[]

98

assertArrayEquals(array1, array2)

99

}

100

101

void testScriptExecution() {

102

// Test script compilation

103

assertScript '''

104

def x = 5

105

def y = 10

106

assert x + y == 15

107

'''

108

109

// Test script with expected result

110

assertScript 'return 2 + 3', 5

111

112

// Use shell for complex testing

113

shell.setVariable('testData', [a: 1, b: 2])

114

def result = evaluate('testData.a + testData.b')

115

assertEquals(3, result)

116

}

117

118

void testStringOperations() {

119

def text = "Hello World"

120

121

assertTrue(text.contains("World"))

122

assertFalse(text.startsWith("world")) // Case sensitive

123

assertEquals(11, text.length())

124

}

125

}

126

```

127

128

### Mock Objects and Stubs

129

130

Create mock objects and stubs for isolation testing with behavior verification.

131

132

```java { .api }

133

/**

134

* Creates mock objects that verify method calls and return values

135

*/

136

class MockFor {

137

/**

138

* Create mock for specified class

139

*/

140

MockFor(Class clazz);

141

142

/**

143

* Define expected method call and return value

144

*/

145

void demand(String methodName);

146

void demand(String methodName, int callCount);

147

void demand(String methodName, int minCalls, int maxCalls);

148

149

/**

150

* Create proxy instance with mock behavior

151

*/

152

Object use(Closure closure);

153

154

/**

155

* Verify all expected calls were made

156

*/

157

void verify();

158

}

159

160

/**

161

* Creates stub objects that return predefined values without verification

162

*/

163

class StubFor {

164

/**

165

* Create stub for specified class

166

*/

167

StubFor(Class clazz);

168

169

/**

170

* Define method behavior without call verification

171

*/

172

void demand(String methodName);

173

void demand(String methodName, Closure returnValue);

174

175

/**

176

* Create proxy instance with stub behavior

177

*/

178

Object use(Closure closure);

179

}

180

```

181

182

**Usage Examples:**

183

184

```groovy

185

import groovy.mock.MockFor

186

import groovy.mock.StubFor

187

import groovy.test.GroovyTestCase

188

189

class EmailServiceTest extends GroovyTestCase {

190

191

void testEmailSending() {

192

// Mock the SMTP service

193

def mockSmtp = new MockFor(SmtpService)

194

195

// Define expected method calls

196

mockSmtp.demand.connect { host, port ->

197

assertEquals("smtp.example.com", host)

198

assertEquals(587, port)

199

return true

200

}

201

202

mockSmtp.demand.authenticate { username, password ->

203

assertEquals("user@example.com", username)

204

return true

205

}

206

207

mockSmtp.demand.sendMessage(1) { message ->

208

assertEquals("Test Subject", message.subject)

209

assertEquals("Test Body", message.body)

210

return "messageId123"

211

}

212

213

mockSmtp.demand.disconnect()

214

215

// Use mock in test

216

mockSmtp.use { smtp ->

217

def emailService = new EmailService(smtp)

218

def result = emailService.sendEmail(

219

to: "recipient@example.com",

220

subject: "Test Subject",

221

body: "Test Body"

222

)

223

224

assertEquals("messageId123", result)

225

}

226

227

// Verify all expected calls were made

228

mockSmtp.verify()

229

}

230

231

void testDatabaseConnectionStub() {

232

// Stub database connection for testing without real DB

233

def stubDb = new StubFor(DatabaseConnection)

234

235

stubDb.demand.query { sql ->

236

// Return fake data based on query

237

if (sql.contains("users")) {

238

return [[id: 1, name: "John"], [id: 2, name: "Jane"]]

239

}

240

return []

241

}

242

243

stubDb.demand.execute { sql ->

244

return 1 // Always return 1 row affected

245

}

246

247

stubDb.use { db ->

248

def userService = new UserService(db)

249

250

def users = userService.getAllUsers()

251

assertEquals(2, users.size())

252

assertEquals("John", users[0].name)

253

254

def result = userService.createUser("Bob", "bob@example.com")

255

assertEquals(1, result)

256

}

257

}

258

259

void testPartialMocking() {

260

// Mock only specific methods of a class

261

def mockFile = new MockFor(FileProcessor)

262

263

mockFile.demand.readFile { filename ->

264

if (filename == "config.properties") {

265

return "key1=value1\nkey2=value2"

266

}

267

throw new FileNotFoundException("File not found: $filename")

268

}

269

270

mockFile.demand.writeFile { filename, content ->

271

assertTrue(filename.endsWith(".backup"))

272

assertTrue(content.contains("value1"))

273

}

274

275

mockFile.use { fileProcessor ->

276

def configManager = new ConfigManager(fileProcessor)

277

configManager.backupConfig("config.properties")

278

}

279

}

280

}

281

```

282

283

### Test Suite Management

284

285

Organize and execute multiple test classes with comprehensive reporting.

286

287

```java { .api }

288

/**

289

* Manages execution of multiple test classes

290

*/

291

class GroovyTestSuite extends TestSuite {

292

/**

293

* Create empty test suite

294

*/

295

GroovyTestSuite();

296

297

/**

298

* Create test suite with name

299

*/

300

GroovyTestSuite(String name);

301

302

/**

303

* Add test class to suite

304

*/

305

void addTestSuite(Class<? extends TestCase> testClass);

306

307

/**

308

* Add individual test method

309

*/

310

void addTest(Test test);

311

312

/**

313

* Load test suite from directory

314

*/

315

static Test suite();

316

static Test suite(String directory);

317

318

/**

319

* Run all tests in suite

320

*/

321

TestResult run();

322

TestResult run(TestResult result);

323

}

324

325

/**

326

* Utility for automatically discovering and running tests

327

*/

328

class AllTestSuite {

329

/**

330

* Create test suite from all test classes in package

331

*/

332

static Test suite();

333

334

/**

335

* Create test suite from specific directory

336

*/

337

static Test suite(String directory);

338

339

/**

340

* Create test suite with custom filter

341

*/

342

static Test suite(Closure filter);

343

}

344

```

345

346

**Usage Examples:**

347

348

```groovy

349

import groovy.test.GroovyTestSuite

350

import groovy.test.AllTestSuite

351

import junit.framework.TestResult

352

353

// Create custom test suite

354

class MyTestSuite extends GroovyTestSuite {

355

356

static Test suite() {

357

def suite = new GroovyTestSuite()

358

359

// Add individual test classes

360

suite.addTestSuite(MathUtilsTest)

361

suite.addTestSuite(StringUtilsTest)

362

suite.addTestSuite(DatabaseTest)

363

suite.addTestSuite(ApiTest)

364

365

return suite

366

}

367

}

368

369

// Run test suite programmatically

370

def suite = MyTestSuite.suite()

371

def result = suite.run()

372

373

println "Tests run: ${result.runCount()}"

374

println "Failures: ${result.failureCount()}"

375

println "Errors: ${result.errorCount()}"

376

377

// Auto-discover all tests in directory

378

class AutoTestSuite {

379

static Test suite() {

380

return AllTestSuite.suite("src/test/groovy")

381

}

382

}

383

384

// Create filtered test suite

385

class IntegrationTestSuite {

386

static Test suite() {

387

return AllTestSuite.suite { testClass ->

388

testClass.name.contains("Integration")

389

}

390

}

391

}

392

393

// Run with custom test runner

394

def runTestsWithReporting() {

395

def suite = AllTestSuite.suite()

396

def result = new TestResult()

397

398

// Add listeners for detailed reporting

399

result.addListener([

400

startTest: { test ->

401

println "Starting: ${test.name}"

402

},

403

endTest: { test ->

404

println "Completed: ${test.name}"

405

},

406

addError: { test, error ->

407

println "ERROR in ${test.name}: ${error.message}"

408

},

409

addFailure: { test, failure ->

410

println "FAILURE in ${test.name}: ${failure.message}"

411

}

412

])

413

414

suite.run(result)

415

return result

416

}

417

```

418

419

### Assertion Utilities

420

421

Extended assertion methods for comprehensive test validation.

422

423

```java { .api }

424

/**

425

* Enhanced assertion utilities for Groovy testing

426

*/

427

class GroovyAssert {

428

/**

429

* Assert that closure throws expected exception

430

*/

431

static void shouldFail(Closure code);

432

static void shouldFail(Class<? extends Throwable> expectedType, Closure code);

433

static void shouldFail(String expectedMessage, Closure code);

434

435

/**

436

* Assert collection equality ignoring order

437

*/

438

static void assertCollectionEquals(Collection expected, Collection actual);

439

static void assertCollectionEquals(String message, Collection expected, Collection actual);

440

441

/**

442

* Assert array equality

443

*/

444

static void assertArrayEquals(Object[] expected, Object[] actual);

445

static void assertArrayEquals(String message, Object[] expected, Object[] actual);

446

447

/**

448

* Assert script execution results

449

*/

450

static void assertScript(String script);

451

static void assertScript(String script, Object expectedResult);

452

453

/**

454

* Assert objects are approximately equal (for floating point)

455

*/

456

static void assertApproximatelyEqual(double expected, double actual, double tolerance);

457

458

/**

459

* Assert string matches pattern

460

*/

461

static void assertMatches(String pattern, String actual);

462

static void assertMatches(String message, String pattern, String actual);

463

}

464

```

465

466

**Usage Examples:**

467

468

```groovy

469

import static groovy.test.GroovyAssert.*

470

import groovy.test.GroovyTestCase

471

472

class AssertionExamplesTest extends GroovyTestCase {

473

474

void testExceptionHandling() {

475

// Test specific exception type

476

shouldFail(IllegalArgumentException) {

477

new BankAccount(-100) // Negative balance not allowed

478

}

479

480

// Test exception message

481

shouldFail("Insufficient funds") {

482

def account = new BankAccount(50)

483

account.withdraw(100)

484

}

485

486

// Test any exception

487

shouldFail {

488

def result = 10 / 0

489

}

490

}

491

492

void testCollectionAssertions() {

493

def list1 = [1, 2, 3, 4]

494

def list2 = [4, 3, 2, 1] // Different order

495

def list3 = [1, 2, 3] // Different size

496

497

// Collections equal regardless of order

498

assertCollectionEquals(list1, list2)

499

500

// Different sizes should fail

501

shouldFail {

502

assertCollectionEquals(list1, list3)

503

}

504

505

def array1 = ["a", "b", "c"] as String[]

506

def array2 = ["a", "b", "c"] as String[]

507

assertArrayEquals(array1, array2)

508

}

509

510

void testScriptAssertions() {

511

// Simple script validation

512

assertScript '''

513

def factorial = { n ->

514

n <= 1 ? 1 : n * factorial(n - 1)

515

}

516

assert factorial(5) == 120

517

'''

518

519

// Script with expected return value

520

assertScript 'return [1, 2, 3].sum()', 6

521

522

// Complex script testing

523

assertScript '''

524

class Person {

525

String name

526

int age

527

528

String toString() { "$name ($age)" }

529

}

530

531

def person = new Person(name: "John", age: 30)

532

return person.toString()

533

''', "John (30)"

534

}

535

536

void testNumericAssertions() {

537

def pi = 3.14159

538

def approximatePi = 22 / 7

539

540

// Floating point comparison with tolerance

541

assertApproximatelyEqual(pi, approximatePi, 0.01)

542

543

shouldFail {

544

assertApproximatelyEqual(pi, approximatePi, 0.001) // Too strict

545

}

546

}

547

548

void testPatternMatching() {

549

def email = "user@example.com"

550

def phoneNumber = "555-123-4567"

551

552

// Regex pattern matching

553

assertMatches(/\w+@\w+\.\w+/, email)

554

assertMatches(/\d{3}-\d{3}-\d{4}/, phoneNumber)

555

556

// Pattern with message

557

assertMatches("Invalid email format", /\w+@\w+\.\w+/, "user@example.com")

558

}

559

}

560

```

561

562

### Integration Testing Helpers

563

564

Utilities for integration testing with external systems and resources.

565

566

**Usage Examples:**

567

568

```groovy

569

import groovy.test.GroovyTestCase

570

571

class IntegrationTestExample extends GroovyTestCase {

572

573

void testDatabaseIntegration() {

574

// Setup test database

575

def sql = Sql.newInstance("jdbc:h2:mem:testdb", "sa", "", "org.h2.Driver")

576

577

try {

578

// Setup test data

579

sql.execute("""

580

CREATE TABLE products (

581

id INT PRIMARY KEY,

582

name VARCHAR(50),

583

price DECIMAL(10,2)

584

)

585

""")

586

587

sql.execute("INSERT INTO products VALUES (1, 'Widget', 19.99)")

588

sql.execute("INSERT INTO products VALUES (2, 'Gadget', 29.99)")

589

590

// Test service with real database

591

def productService = new ProductService(sql)

592

def products = productService.getAllProducts()

593

594

assertEquals(2, products.size())

595

assertTrue(products.any { it.name == "Widget" })

596

597

// Test product creation

598

productService.createProduct("Doohickey", 39.99)

599

def allProducts = productService.getAllProducts()

600

assertEquals(3, allProducts.size())

601

602

} finally {

603

sql.close()

604

}

605

}

606

607

void testFileSystemOperations() {

608

// Create temporary test directory

609

def testDir = File.createTempDir("groovy-test", "")

610

611

try {

612

def fileService = new FileService(testDir.absolutePath)

613

614

// Test file creation

615

fileService.createFile("test.txt", "Hello World")

616

assertTrue(new File(testDir, "test.txt").exists())

617

618

// Test file reading

619

def content = fileService.readFile("test.txt")

620

assertEquals("Hello World", content)

621

622

// Test file listing

623

def files = fileService.listFiles()

624

assertEquals(1, files.size())

625

assertEquals("test.txt", files[0])

626

627

} finally {

628

// Cleanup test directory

629

testDir.deleteDir()

630

}

631

}

632

633

void testWebServiceIntegration() {

634

// Mock HTTP client for web service testing

635

def mockHttp = new MockFor(HttpClient)

636

637

mockHttp.demand.get { url ->

638

if (url.contains("/api/users/1")) {

639

return [status: 200, body: '{"id": 1, "name": "John Doe"}']

640

}

641

return [status: 404, body: '{"error": "Not found"}']

642

}

643

644

mockHttp.use { httpClient ->

645

def webService = new UserWebService(httpClient)

646

647

def user = webService.getUser(1)

648

assertEquals("John Doe", user.name)

649

650

shouldFail {

651

webService.getUser(999) // Should throw exception for 404

652

}

653

}

654

}

655

}

656

```

657

658

## Types

659

660

### Test Framework Types

661

662

```java { .api }

663

/**

664

* Base test case class with Groovy enhancements

665

*/

666

abstract class GroovyTestCase extends TestCase {

667

/**

668

* Get the Groovy shell used for script evaluation

669

*/

670

GroovyShell getShell();

671

672

/**

673

* Set custom binding for shell

674

*/

675

void setShell(GroovyShell shell);

676

677

/**

678

* Evaluate Groovy script in test context

679

*/

680

Object evaluate(String script);

681

}

682

683

/**

684

* Test suite for organizing multiple tests

685

*/

686

class GroovyTestSuite extends TestSuite {

687

/**

688

* Add test class to the suite

689

*/

690

void addTestSuite(Class<? extends TestCase> testClass);

691

692

/**

693

* Get count of tests in suite

694

*/

695

int countTestCases();

696

697

/**

698

* Run all tests with custom result handler

699

*/

700

TestResult run(TestResult result);

701

}

702

```

703

704

### Mock and Stub Types

705

706

```java { .api }

707

/**

708

* Mock object creator with call verification

709

*/

710

class MockFor {

711

/**

712

* The class being mocked

713

*/

714

Class getMockedClass();

715

716

/**

717

* Define expected method behavior

718

*/

719

void demand(String methodName, Closure implementation);

720

void demand(String methodName, int callCount, Closure implementation);

721

722

/**

723

* Create and use mock instance

724

*/

725

Object use(Closure closure);

726

727

/**

728

* Verify all expected calls were made

729

*/

730

void verify();

731

}

732

733

/**

734

* Stub object creator without call verification

735

*/

736

class StubFor {

737

/**

738

* The class being stubbed

739

*/

740

Class getStubbedClass();

741

742

/**

743

* Define method behavior

744

*/

745

void demand(String methodName, Closure implementation);

746

747

/**

748

* Create and use stub instance

749

*/

750

Object use(Closure closure);

751

}

752

```