views:

197

answers:

3

hello guys.i've just come into the world of easymock.i'll like to ask if easymock only does mock object for interfaces? So in my effort to understand i wrote a class to generate unique voucher in java.i obviously can't know which value it will generate to use in the assert stuff.So how to make sure the generated voucher is of the type long?

here is the function

 public static Long generateID(int length) {
    logger.info("Calling generateID with specify length");
    Long result = null;

    if (length > 0) {
        StringBuffer id = new StringBuffer(length);
        for (int i = 0; i < length; i++) {
            id.append(NUMS[(int)Math.floor(Math.random() * 20)]);
        }
        result = Long.parseLong(id.toString());
    }

    return result;
}

here is the test class

@Before
public void setUp() {
    mockgenerator = createMock(VGenerator.class);
}


/**
 * Test of generateID method, of class VGenerator.
 */
@Test
public void testGenerateID() {
   Long exp = (long)1;
   int length = 15;
    expect(mockgenerator.generateID(length)).equals(Long.class);
    replay(mockgenerator);
    long res = mockgenerator.generatedID(length);
    assertEquals(exp.class, res.class);
}

well this might look terrific to you but i'm still confused about how to do this thanks for helping

+2  A: 

I believe you misunderstand how easymock is used, Calling expect tells the mock object that when you are replaying it, this call should be called. Appending .andReturn() Tells the mock object to return whatever you put in there, in my example a long value of 1. The point of easymock is that you do not need to implement the mocked interface to test the classses that use it. By mocking you can isolate a class from the classes it depends on and only test the contained code of the class your are currently testing.

interface VGenerator {
     public Long generateID(int in);
}


@Before
public void setUp() {
    mockgenerator = createMock(VGenerator.class);
}


@Test
public void testGenerateID() {
     int length = 15;
     expect(mockgenerator.generateID(length)).andReturn(new Long(1));
     replay(mockgenerator);
     myMethodToBeTested();
     verify(mockgenerator);
}

public void myMethodToBeTested(){
    //do stuff
    long res = mockgenerator.generatedID(length);
    //do stuff
}

If I misunderstood your question and it was really, does easymock only mock interfaces? then the answer is Yes, Easymock only mocks interfaces. Read the documentation for more help Easymock

Andrew
very good explanation.I like it.thanks
black sensei
A: 

If it is absolutely crucial that the return type is long, and you want to make sure that future changes don't inadvertently change this, then you don't need easymock. Just do this:

@Test
public void TestGenerateIDReturnsLong()
{
   Method method = 
      VGenerator.class.getDeclaredMethod("generateID", new Class[0]);
   Assert.Equals(long.Class, method.GetReturnType());
}

Currently you are generating a mock implementation of VGenerator, and then you test the mock. This is not useful. The point of unit testing is to test a real implementation. So now you might be wondering what mocks are good for?

As an example, imagine that VGenerator needs to use a random number generator internally, and you provide this in the constructor (which is called "dependency injection"):

public VGenerator
{
    private final RandomNumberGenerator rng; 

    // constructor
    public VGenerator(RandomNumberGenerator rng)
    {
       this.rng = rng;
    }

    public long generateID(length)
    {
       double randomNumber = this.rng.getRandomNumber();
       // ... use random number in calculation somehow ...
       return id;
    }
}

When implementing VGenerator, you are not really interested in testing the random number generator. What you are interested in is how VGenerator calls the random number generator, and how it uses the results to produce output. What you want is to take full control of the random number generator for the purpose of testing, so you create a mock of it :

@Test
public void TestGenerateId()
{
   RandomNumberGenerator mockRNG = createMock(RandomNumberGenerator.class);
   expect(mockRNG.getRandomNumber()).andReturn(0.123);
   replay(mockRNG);

   VGenerator vgenerator = new VGenerator(mockRNG);
   long id = vgenerator.generateID();
   Assert.Equals(5,id); // e.g. given random number .123, result should be 5

   verify(mockRNG);
}
Wim Coenen
i appreciate the explanation.thanks
black sensei
A: 

EasyMock Class extension can mock classes. It is an extension to EasyMock. It still can mock interface so it's pretty much a replacement to EasyMock.

However, in your case you are trying to mock a static method. Static method can't be mocked since they can't be overloaded. You need class instrumentation to do so which EasyMock doesn't do.