Skip to content

Stubs and scenario

dfurodet edited this page Nov 22, 2011 · 1 revision

Stubs and scenario

This section explains how to create the two main elements relying on mocks:

  • Stubs: to simulate methods referenced by the objects under test
  • Expectations: to validate the behavior of a test regarding a given scenario

Defining stubs

The great advantage of mocking frameworks versus classical stubs is that they allow you to stub only the invocations used by your test. Using stubs, you can say what exactly will happen when the tested application invokes a specific method with specific arguments.

Next is an example of a stub that simulates the returning of a value, using a mock of a List:


import static com.vmware.lmock.masquerade.Schemer.*;
...
public class MyTest {
  final List mockList = Mock.getObject("mock list", List.class);
  ...
  void aTestIllustratingStubs() {
    begin();
    // Define two stubs: one simulates the fact that the list is not empty, the second one that
    // the first string in the list is "Hello World":
    willReturn(false).when(myList).isEmpty();
    willReturn("Hello World").when(myList).get(0);

    // THE TEST ...
    ...
    end();
  }
}

As you may have noticed, the generic syntax of a stub definition is:

  • The definition of a behavior (e.g. willReturn)
  • The specification of the implied mock, using when
  • The invoked method, along with the expected parameters for this invocation

Defining a scenario

The real added value of a mocking framework compared to simple stubs is that it extends the simplistic stubbing mechanism to verify that the tested application complies with a pre-defined scenario. The example above expresses the fact that "if the application checks that the list is empty or not, the answer is no"... A mocking framework allows to extend this type of assumption to expectations like "the application will verify that the list is not empty".

To do this, you must specify an occurrence for the implied invocation, as illustrated below:


import static com.vmware.lmock.masquerade.Schemer.*;
import com.vmware.lmock.checker.Occurrences;
...
public class MyTest {
  final List mockList = Mock.getObject("mock list", List.class);
  ...
  void aTestIllustratingExpectations() {
    begin();
    // When running the test, we expect that the user will check that the list
    // is not empty. This should happen at least one time.
    willInvoke(Occurrences.atLeast(1)).willReturn(false).when(myList).isEmpty();
    // Then, the user will request the first element in the list, exactly one
    // time.
    willInvoke(1).willReturn("Hello World").when(myList).get(0);
    // Finally, we expect that the application will clear the requested list.
    // Since this is a void method, we do not need to specify a resulting
    // behavior. In that case, the "of" keyword is used to express the expectation.
    willInvoke(1).of(myList).clear();
    // THE TEST ...
    ...
    end();
  }
}

From the above example we can see that:

  • An expectation requires an occurrence specification
  • An expectation may apply to a void method

You must keep in mind that a scenario is considered as a sequence of expectations, a kind of checklist that Lmock uses to validate the test. When the test executes, Lmock raises an error if:

  • If a mock is invoked by the test, if no stub covers that invocation and the checklist does not currently expect that this invocation happens
  • At the end of the test, if the checklist in incomplete (i.e. some invocations are missing)... This is the main goal of end

Stubs prevail on Mocks

Lmock puts a priority on stubs. In other words, if you define a stub and an expectation for a similar invocation, the stub is always considered first.

Something went wrong with that request. Please try again.