当前位置: 首页 > 知识库问答 >
问题:

JMockIt模拟方法不模拟

嵇浩然
2023-03-14
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");
}

上面还有第二个问题。当我在Expects块中定义mock类时(如上),似乎只调用了行()构造函数,而不是行(Object),因此没有正确初始化对象。我通过将它移到@beforeTest方法中并在那里实例化该类来解决这个问题。看起来是这样的:

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()。有什么见解吗?

共有1个答案

长孙兴德
2023-03-14

我终于能够编写我的测试,这样就调用了正确的构造函数,并且没有发生实际的数据库操作。我想我遇到的部分问题是Expections块中的一个方法得到了一个不同于我对一个参数不感兴趣的对象。我认为我的问题的另一部分是混淆了模拟类和期望录音的角色。

测试中的代码没有改变。为了方便起见,下面是我的简化示例:

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);
}
 类似资料:
  • 我试图模拟一个单例类(SessionDataManager),通过调用静态getInstance()方法获得一个实例,但所有尝试似乎都返回null。 我试过了

  • 我这样做是为了得到想要的结果

  • 我试图在测试中模拟一个调用,但我得到了一个错误,因为它调用了真正的方法,而不是模拟它。 这是我的方法 } 这是我的测试课 测试实际上调用了受保护的方法config Setter,并在设置代理时失败。帮助我理解我在这里做错了什么。

  • 问题内容: 我正在使用Mockito创建测试。在测试中,我正在创建类型的对象。当我运行此测试时,出现错误: 这是最小的代码: 如何避免此错误? 问题答案: 您正在使用的是专为模拟而设计的库,它缺少实现。因为您的测试实际上是在对象上调用方法,而没有使用模拟库来赋予其行为,所以它会向您发送该消息。 如“ Android单元测试支持”页面上所示: “方法……不嘲笑。” 用于运行单元测试的android.

  • 关于@mocked声明为junit测试的实例变量,如@mocked ClassB ClassB: (1)对于junit,实例变量是为每个测试新创建的(比如test1()、test2()),对吗?在每个测试运行之前,是否会创建一个新的模仿的ClassB实例? (2)它嘲笑班级。它使ClassB中的所有方法对所有测试(在本例中是test1()和test2())都是模拟的,对吗?