JMockIt 模拟方法不模拟
JMockIt Mocked Method not Mocking
[10/7/06 4:00 编辑示例代码]
我正在尝试在不接触数据库的情况下测试一些代码(将 JMockIt 与 TestNG 结合使用),但看起来实际上仍在调用模拟方法。这是简化的设置:
class DBRow {
public DBRow() { }
public DBRow(Object obj) {
initialize(obj);
}
public void insert() {
actuallyAddRowToDatabase();
}
}
class MyObject extends DBRow {
MyObject(Object obj) {
super(obj);
}
public void insert(Object obj) {
doSomething(obj);
insert();
}
}
class Factory {
static MyObject createObject(Object obj1, Object obj2) {
MyObject newObj = new MyObject(obj1);
newObj.insert(obj2);
return newObj;
}
}
我想模拟插入操作以防止在实际数据库中插入,所以我尝试了这样的操作:
@Test
public void testCreation() {
new Expectations(MyObject.class) {
MyObject mock = new MyObject(null) {
@Mock
public void insert(Object obj) { }
};
{
new MyObject(anyString); result = mock;
}};
MyObject test = Factory.createObject("something", "something else");
}
不过貌似真正的insert(Object)
还在调用。我指定 class 被模拟,所以所有实例都应该被模拟,对吧?而且我指定应该模拟插入方法,那么为什么要调用真正的方法?
上面还有第二个问题。当我在 Expectations 块中定义模拟 class 时(如上所述),似乎只调用了 Row()
构造函数而不是 Row(Object)
,因此对象未正确初始化。我通过将它移动到 @BeforeTest
方法并在那里实例化 class 来解决这个问题。这是它的样子:
private MyObject mock;
@BeforeTest
public void beforeTest() {
new MockUp<MyObject>() {
@Mock
public void insert(Object obj) { }
};
mock = new MyObject("something");
}
@Test
public void testCreation() {
new Expectations(MyObject.class) {{
new MyObject(anyString); result = mock;
}};
MyObject test = Factory.createObject("something", "something else");
}
所以这似乎调用了正确的构造函数,但似乎 insert()
也被调用了。有什么见解吗?
您没有使用模拟对象来调用您的函数,即 private MyObject mock;
,而是一个真实的对象 test
、
MyObject test = new MyObject("something", "something else");
在 mock
而不是 test
上调用 testStuff()
。
不会自动模拟所有实例,您必须使用模拟实例。
我终于能够编写我的测试,以便调用正确的构造函数并且不会发生实际的数据库操作。我认为我遇到的部分问题是 Expectations 块中的一种方法得到的对象与我对我不感兴趣的参数的预期不同。我认为我的问题的另一部分是混淆MockUp class 和 Expectations 录音的角色。
被测代码没有改变。为方便起见,这里又是我的简化示例:
class DBRow {
public DBRow() { }
public DBRow(Object obj) {
initialize(obj);
}
public void insert() {
actuallyAddRowToDatabase();
}
}
class MyObject extends DBRow {
MyObject(Object obj) {
super(obj);
}
public void insert(Object obj) {
doSomething(obj);
insert();
}
}
class Factory {
static MyObject createObject(Object obj1, Object obj2) {
MyObject newObj = new MyObject(obj1);
newObj.insert(obj2);
return newObj;
}
}
这基本上是我最终得到的测试代码:
Object something;
Object somethingElse;
@BeforeTest
public void beforeTest() {
new MockUp<MyObject>() {
@Mock
public void insert() { } // override the "actual" DB insert
}; // of Row.insert()
}
@Test
public void testCreation() {
MyObject mock = new MyObject(something); // object correctly init'd
// by Row.initialize(Object)
new Expectations(MyObject.class) {{
new MyObject(something); result = mock;
mock.insert(somethingElse);
}};
MyObject test = Factory.createObject(something, somethingElse);
}
关键点是 A) 我创建了一个 MockUp class 来覆盖数据库操作,并且 B) 创建了该部分模拟实例的本地实例来记录我的期望。
[10/7/06 4:00 编辑示例代码] 我正在尝试在不接触数据库的情况下测试一些代码(将 JMockIt 与 TestNG 结合使用),但看起来实际上仍在调用模拟方法。这是简化的设置:
class DBRow {
public DBRow() { }
public DBRow(Object obj) {
initialize(obj);
}
public void insert() {
actuallyAddRowToDatabase();
}
}
class MyObject extends DBRow {
MyObject(Object obj) {
super(obj);
}
public void insert(Object obj) {
doSomething(obj);
insert();
}
}
class Factory {
static MyObject createObject(Object obj1, Object obj2) {
MyObject newObj = new MyObject(obj1);
newObj.insert(obj2);
return newObj;
}
}
我想模拟插入操作以防止在实际数据库中插入,所以我尝试了这样的操作:
@Test
public void testCreation() {
new Expectations(MyObject.class) {
MyObject mock = new MyObject(null) {
@Mock
public void insert(Object obj) { }
};
{
new MyObject(anyString); result = mock;
}};
MyObject test = Factory.createObject("something", "something else");
}
不过貌似真正的insert(Object)
还在调用。我指定 class 被模拟,所以所有实例都应该被模拟,对吧?而且我指定应该模拟插入方法,那么为什么要调用真正的方法?
上面还有第二个问题。当我在 Expectations 块中定义模拟 class 时(如上所述),似乎只调用了 Row()
构造函数而不是 Row(Object)
,因此对象未正确初始化。我通过将它移动到 @BeforeTest
方法并在那里实例化 class 来解决这个问题。这是它的样子:
private MyObject mock;
@BeforeTest
public void beforeTest() {
new MockUp<MyObject>() {
@Mock
public void insert(Object obj) { }
};
mock = new MyObject("something");
}
@Test
public void testCreation() {
new Expectations(MyObject.class) {{
new MyObject(anyString); result = mock;
}};
MyObject test = Factory.createObject("something", "something else");
}
所以这似乎调用了正确的构造函数,但似乎 insert()
也被调用了。有什么见解吗?
您没有使用模拟对象来调用您的函数,即 private MyObject mock;
,而是一个真实的对象 test
、
MyObject test = new MyObject("something", "something else");
在 mock
而不是 test
上调用 testStuff()
。
不会自动模拟所有实例,您必须使用模拟实例。
我终于能够编写我的测试,以便调用正确的构造函数并且不会发生实际的数据库操作。我认为我遇到的部分问题是 Expectations 块中的一种方法得到的对象与我对我不感兴趣的参数的预期不同。我认为我的问题的另一部分是混淆MockUp class 和 Expectations 录音的角色。
被测代码没有改变。为方便起见,这里又是我的简化示例:
class DBRow {
public DBRow() { }
public DBRow(Object obj) {
initialize(obj);
}
public void insert() {
actuallyAddRowToDatabase();
}
}
class MyObject extends DBRow {
MyObject(Object obj) {
super(obj);
}
public void insert(Object obj) {
doSomething(obj);
insert();
}
}
class Factory {
static MyObject createObject(Object obj1, Object obj2) {
MyObject newObj = new MyObject(obj1);
newObj.insert(obj2);
return newObj;
}
}
这基本上是我最终得到的测试代码:
Object something;
Object somethingElse;
@BeforeTest
public void beforeTest() {
new MockUp<MyObject>() {
@Mock
public void insert() { } // override the "actual" DB insert
}; // of Row.insert()
}
@Test
public void testCreation() {
MyObject mock = new MyObject(something); // object correctly init'd
// by Row.initialize(Object)
new Expectations(MyObject.class) {{
new MyObject(something); result = mock;
mock.insert(somethingElse);
}};
MyObject test = Factory.createObject(something, somethingElse);
}
关键点是 A) 我创建了一个 MockUp class 来覆盖数据库操作,并且 B) 创建了该部分模拟实例的本地实例来记录我的期望。