2009-08-13 57 views
2

我刚进入easymock.i'll''''''''''''''''''''''''''''''s'all要求如果easymock只是模拟对象的接口? 因此,在我努力理解的情况下,我写了一个类来在java.i中生成唯一凭证,显然无法知道它将在assert stuff中使用哪个值。因此,如何确保生成的凭证的类型是long?使用easymock验证对象类型

这里是功能

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

以及这可能看起来棒极了你,但我仍然感到困惑如何做到这一点 感谢帮助

+0

如果generateID()试图返回不是很长的东西,那么该类甚至不会编译。 – 2009-08-13 21:05:31

回答

0

如果确定返回类型为long并且您希望确保未来的更改不会无意中更改此设置,那么您不需要easymock。只是这样做:

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

目前正在生成模拟实现的VGenerator,然后测试模拟。这是不是有用。单元测试的重点是测试一个真正的实现。所以现在你可能想知道mock有什么好处?

作为一个例子,假设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); 
} 
+0

我欣赏解释。谢谢 – 2009-08-14 10:03:20

3

我相信你误解了如何使用easymock, 调用expect期间告诉模拟对象,当你重放它时,这应该调用call。 Append .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

+0

非常好的解释。我喜欢它。感谢 – 2009-08-14 09:39:21

0

EasyMock Class extension可以模拟类。它是EasyMock的扩展。它仍然可以模拟接口,所以它几乎是EasyMock的替代品。

但是,在你的情况下,你试图嘲笑一种静态方法。静态方法不能被嘲笑,因为它们不能被重载。你需要班级仪器来做这些EasyMock不能做的事情。