classes

Classes inside specs

Behave specs are ordinary Raku files, so any Raku declaration works inside them, including class, role, and enum. Declare fixture types with my class / my role / my enum so they stay lexical to the spec file: they don't pollute the loader's package, they don't collide with same-named declarations in other specs, and their .^name reads as the short name you wrote.

Declaring a class in a describe

use BDD::Behave;

describe 'Widget', {
  my class Widget {
    has $.bar;
    has $.baz;

    submethod BUILD(:$!bar) {
      $!baz = 42;
    }
  }

  it 'sets attributes', {
    my $w = Widget.new(:bar(17));
    expect($w.bar).to.be(17);
    expect($w.baz).to.be(42);
  }
}

The class lives in the lexical scope of the describe body, so it is visible to nested context blocks and every it inside them.

Storing instances with let

For values you want freshly built per example with optional memoization, combine my class with let:

describe 'Widget', {
  my class Widget {
    has $.bar;
  }

  let(:widget, { Widget.new(:bar(99)) });

  it 'reads via the context parameter', -> $_ {
    expect(.widget.bar).to.be(99);
  }

  it 'reads via the bareword', {
    expect(widget.bar).to.be(99);
  }
}

Each example gets its own memoized instance: the let block runs once per example, never carries over.

Roles and enums

Roles and enums work the same way:

describe 'Greet role', {
  my role Greet { method hi { 'hi' } }
  my class WithGreet does Greet { }

  it 'composes', {
    expect(WithGreet.new.hi).to.be('hi');
  }
}

describe 'Color enum', {
  my enum Color <Red Green Blue>;

  it 'has correct ordinals', {
    expect(Red.Int).to.be(0);
    expect(Blue.Int).to.be(2);
  }
}

Top-level vs in-block

Classes can also be declared at the top of the spec file, before any describe. Pick whichever scope is narrowest for the class's intended use:

  • Top-level when several describe blocks share the type.

  • Inside describe when the type is only meaningful for one group of examples. Keeping it local makes the relationship between the type and the tests obvious.

In both positions, use my class (not class) for the same reasons given above. File-scope class Foo { } is sugar for our class Foo { } and installs Foo into the spec loader's package, where it can collide with other specs and grow a package-qualified .^name.

See Variables in specs for the same scoping rules applied to plain my/our variables.

BDD::Behave v0.9.4

Behavior driven development framework

Authors

  • Greg Donald

License

Artistic-2.0

Dependencies

Provides

  • BDD::Behave
  • BDD::Behave::Benchmark
  • BDD::Behave::Benchmark::Baseline
  • BDD::Behave::Benchmark::Format
  • BDD::Behave::Bisect
  • BDD::Behave::Colors
  • BDD::Behave::Configuration
  • BDD::Behave::Coverage
  • BDD::Behave::DSL
  • BDD::Behave::Diff
  • BDD::Behave::DocExtractor
  • BDD::Behave::DryRun
  • BDD::Behave::Expectation
  • BDD::Behave::Failure
  • BDD::Behave::FailureStore
  • BDD::Behave::Failures
  • BDD::Behave::Files
  • BDD::Behave::Formatter
  • BDD::Behave::Formatter::Documentation
  • BDD::Behave::Formatter::HTML
  • BDD::Behave::Formatter::JSON
  • BDD::Behave::Formatter::JUnit
  • BDD::Behave::Formatter::JsonEvents
  • BDD::Behave::Formatter::Progress
  • BDD::Behave::Formatter::Registry
  • BDD::Behave::Formatter::TAP
  • BDD::Behave::Formatter::Tree
  • BDD::Behave::LetRuntime
  • BDD::Behave::Matcher
  • BDD::Behave::Matcher::Async
  • BDD::Behave::Matcher::Boolean
  • BDD::Behave::Matcher::Change
  • BDD::Behave::Matcher::Collection
  • BDD::Behave::Matcher::Core
  • BDD::Behave::Matcher::Custom
  • BDD::Behave::Matcher::Exception
  • BDD::Behave::Matcher::Numeric
  • BDD::Behave::Matcher::String
  • BDD::Behave::Matcher::Type
  • BDD::Behave::Mock::Allow
  • BDD::Behave::Mock::ArgMatcher
  • BDD::Behave::Mock::Double
  • BDD::Behave::Mock::HaveReceived
  • BDD::Behave::Mock::Spy
  • BDD::Behave::Mock::Stub
  • BDD::Behave::Parallel
  • BDD::Behave::Parallel::Distribution
  • BDD::Behave::Parallel::EventStream
  • BDD::Behave::Parallel::Manifest
  • BDD::Behave::Parallel::Queue
  • BDD::Behave::Parallel::WorkerPool
  • BDD::Behave::Runner
  • BDD::Behave::SharedContexts
  • BDD::Behave::SharedExamples
  • BDD::Behave::Slang
  • BDD::Behave::SpecLoader
  • BDD::Behave::SpecRegistry
  • BDD::Behave::SpecTree
  • BDD::Behave::SpecTree::Core
  • BDD::Behave::SpecTree::Example
  • BDD::Behave::SpecTree::ExampleGroup
  • BDD::Behave::SpecTree::Suite
  • BDD::Behave::Time
  • BDD::Behave::TypeName
  • BDD::Behave::Version
  • BDD::Behave::Watch
  • BDD::Behave::Watch::Session
  • BDD::Behave::Watch::SmartSelector
  • BDD::Behave::Watch::UI
  • BDD::Behave::Watch::Watcher
  • BDD::Behave::Worker

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.