Search code examples
javajunitjmock

JMock: expected once, never invoked


I tried to expect my getFirstName() to return "Jackson" and getLastName() to return "Chin", then i execute the setStaffName() so that the name instance is created and initialized with "Jackson" and "Chin". However, it says it was never invoked. What does never invoked means?

Im new to JMock, can anyone tell me the problem in my code? Any Solutions?

not all expectations were satisfied
expectations:
  ! expected once, never invoked: name.getFirstName(); returns "Jackson"
  ! expected once, never invoked: name.getLastName(); returns "Chin"
what happened before this: nothing!

Above is the error it shows, below are my code..

package userManual;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.imposters.ByteBuddyClassImposteriser;
import org.junit.Test;


public class StaffTest {
    Mockery testName = new Mockery(){{
        setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
    }};
    @Test
    public void testStaffNameInitialization() {
        final Name name = testName.mock(Name.class);

        Staff staff = new Staff();

        final String firstName = "Jackson";
        final String lastName = "Chin";

        //expectations
        testName.checking(new Expectations() {{
            oneOf(name).getFirstName(); will(returnValue(firstName));
            oneOf(name).getLastName(); will(returnValue(lastName));
        }});

        //execute
        staff.setStaffName(firstName, lastName);

        //verify
        testName.assertIsSatisfied();

    }
}

This is my Name Class

public class Name {
    private String firstName;
    private String lastName;
    int i;

    public Name() {}

    public Name(String firstName, String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName(){
        return firstName;
    }

    public void setFirstName(String firstName){
        this.firstName = firstName;
    }

    public String getLastName(){
        return lastName;
    }

    public void setLastName(String lastName){
        this.lastName = lastName;
    }

    public String toString() {
        return String.format("%s %s", firstName, lastName);
    }
}

This is my Staff Class

package userManual;

public class Staff{
    protected String staffId;
    protected String staffPassword;
    protected String staffPhoneNo;
    protected String staffPosition;
    protected Name staffName;

    public Staff() {}

    public Staff(String staffId, String firstName, String lastName, String staffPassword, String staffPhoneNo, String staffPosition){
        this.staffName = new Name(firstName, lastName);
        this.staffId = staffId;
        this.staffPassword = staffPassword;
        this.staffPhoneNo = staffPhoneNo;
        this.staffPosition = staffPosition;
    }

    public Name getStaffName() {
        return staffName;
    }

    public void setStaffName(String firstName, String lastName) {
        this.staffName = new Name(firstName, lastName);
    }
 ...
}

Solution

  • What does never invoked means?

    I means that the methods getFirstName() and getLastName() doesn't get executed by anyone. And by looking at the source codes of your classes Name and Staff that is correct, there is no getFirstName() and getLastName() call anywhere. However, with your code

     //expectations
     testName.checking(new Expectations() {{
         oneOf(name).getFirstName(); will(returnValue(firstName));
         oneOf(name).getLastName(); will(returnValue(lastName));
     }});
    

    you wrote, you expect that these methods are called.

    When you write testName.assertIsSatisfied(); it will check if it did. In your case it didn't and so you will get the assert message from above.

    Depending on what you want to test here you need to rewrite the JMock expectations for what you want to test/mock or don't use any mocking at all. Keep in mind that "mocking" is not a replacement for simple JUnit assertions like assertEquals().