使用easymock验证对象类型

时间:2009-08-13 17:32:41

标签: java unit-testing junit easymock

我刚刚进入easymock的世界。我想问一下easymock是否只为接口做模拟对象?  所以在我努力理解我写了一个类来生成java.i中的唯一凭证时,显然无法知道它将在assert中使用哪个值。那么如何确保生成的凭证类型为long?< / p>

这是函数

 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;
}

这是测试类

@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);
}

这对你来说可能看起来很棒,但我仍然对如何做到这一点感到困惑 谢谢你的帮助

3 个答案:

答案 0 :(得分:3)

我相信你误解了easymock的使用方式, 调用expect告诉模拟对象,当你重放它时,应该调用这个调用。追加.andReturn()告诉模拟对象返回你放在那里的任何内容,在我的例子中,长值为1。 easymock的要点是你不需要实现模拟接口来测试使用它的类。通过模拟,你可以将类与它所依赖的类隔离开来,只测试包含的代码你正在测试的课程。

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
}

如果我误解了你的问题并且它确实存在,那么easymock只会模拟接口吗?那么答案是肯定的,Easymock只能模拟界面。阅读文档以获取更多帮助Easymock

答案 1 :(得分:0)

如果返回类型为long绝对至关重要,并且您希望确保将来的更改不会无意中更改,那么您不需要easymock。就这样做:

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

目前,您正在生成VGenerator的模拟实现,然后测试模拟。这有用。单元测试的关键是测试一个真正的实现。所以现在你可能想知道什么样的嘲笑有用?

作为一个例子,假设VGenerator需要在内部使用随机数生成器,并在构造函数中提供它(称为“依赖注入”):

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;
    }
}

实施VGenerator时,您对测试随机数生成器并不感兴趣。您感兴趣的是VGenerator如何调用随机数生成器,以及它如何使用结果生成输出。您想要的是完全控制随机数生成器以进行测试,因此您可以创建它的模拟 :

@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);
}

答案 2 :(得分:0)

EasyMock Class extension可以模拟类。它是EasyMock的扩展。它仍然可以模拟界面,因此它几乎是EasyMock的替代品。

但是,在您的情况下,您正在尝试模拟静态方法。静态方法不能被模拟,因为它们不能被重载。您需要使用类检测来执行此操作,EasyMock不会这样做。