在单元测试中,如何替换域对象上的接口方法?

时间:2013-01-27 02:31:45

标签: grails groovy junit

我正在使用Groovy 1.8.6和Grails 2.1.1

我有一个界面

public interface Searchable{
    Long docVersion()
}

由对象实现

class Book implements Searchable {
    Long docVersion() {
        System.currentTimeMillis() / 1000L
    }

    String otherMethod() {
        "toto"
    }
}

并进行测试

@Mock([Book])
class SomeBookTester {
    @Before
    void setup() {
        Book.metaclass.docVersion = {-> 12345}
        Book.metaclass.otherMethod = {-> "xyz"}
    }

    @Test
    void test1() {
        assert 12345 == new Book().docVersion()
    }

    @Test
    void test2() {
        assert "xyz" == new Book().otherMethod()
    }
}

第一次测试总是失败,因为替代方法不起作用。我怎么能解决这个问题?有什么问题?

2 个答案:

答案 0 :(得分:2)

您最好使用正确的GrailsMock工具。你可以试试这个:

@Mock([Book])
class SomeBookTester {
    @Before
    void setup() {
        def mockBook = mockFor(Book)
        mockBook.demand.docVersion(0..1)  { -> 12345 }
        mockBook.demand.otherMethod(0..1) { -> "xyz" }
        Book.metaClass.constructor =  { -> mockBook.createMock() }
    }

    @Test
    void test1() {
        assert 12345 == new Book().docVersion()
    }

    @Test
    void test2() {
        assert "xyz" == new Book().otherMethod()
    }
}

答案 1 :(得分:1)

这对我有用

我改变了这样的类:

class Book implements Searchable {
    Long docVersion() {
        currentTime()
    }

    Long currentTime() {
        System.currentTimeMillis() / 1000L
    }

    String otherMethod() {
        "toto"
    }
}

在测试中,我替换 currentTime 方法

@Mock([Book])
class SomeBookTester {
    @Before
    void setup() {
        Book.metaclass.currentTime= {-> 12345}
        Book.metaclass.otherMethod = {-> "xyz"}
    }

    @Test
    void test1() {
        assert 12345 == new Book().docVersion()
    }

    @Test
    void test2() {
        assert "xyz" == new Book().otherMethod()
    }
}

测试通过