java - 模拟方法间依赖

标签 java unit-testing mocking

我最近开始在我的测试中使用模拟对象,但我对它们仍然非常缺乏经验,并且不确定在某些情况下如何使用它们。目前我正在为如何模拟方法间依赖性(调用方法 A 对方法 B 的结果有影响)而苦苦挣扎,以及它是否应该被模拟(在使用模拟框架的意义上)?

以 Java 迭代器为例?模拟 next() 调用以返回正确的值很容易,但是我如何模拟 hasNext(),这取决于 next() 被调用了多少次?目前我正在使用 List.Iterator,因为我找不到正确模拟一个的方法。

Martin Fowler 对 mock 和 stub 的区分是否在这里发挥作用?我应该编写自己的 IteratorMock 吗?

还要考虑以下示例。要测试的方法调用 mockObject.setX() 和后来的 mockObject.getX()。有什么方法可以创建这样一个模拟(无需编写自己的模拟),它允许 getX 的返回值取决于传递给 setX 的值吗?

最佳答案

在一般情况下,我会遵循上述 djna 的建议并为这两种方法设置期望值。但是对于给出的示例,我可能不会使用模拟,而是使用 API 创建一个包含我想要的数据的集合,并从中检索迭代器。 (Arrays.asList(...).iterator())。

编辑:回复:设置/获取 你还用这个对象做什么?如果它是一个值对象(仅获取/设置),我不会 mock 它。付出再多的努力也无济于事。如果不是,则使用 easyMock:

import org.apache.commons.lang.mutable.MutableInt;
import org.easymock.IAnswer;
import org.junit.Test;
import static org.easymock.EasyMock.*;

public class TestSet {
    @Test
    public void testSetGet() {
        final MutableInt value = new MutableInt();

        GetSetId id = createMock(GetSetId.class);
        id.setID(anyInt());
        expectLastCall().andAnswer(new IAnswer<Object>() {

            @Override
            public Object answer() throws Throwable {
                Object[] arguments = getCurrentArguments();
                value.setValue((Integer) arguments[0]);
                return null;
            }

        });
        expect(id.getID()).andAnswer(new IAnswer<Integer>() {

            @Override
            public Integer answer() throws Throwable {

                return value.toInteger();
            }

        });

        replay(id);
        id.setID((int) (Math.random() * 100.0));
        System.out.println(id.getID());
        verify(id);
    }
}

interface GetSetId {
    public int getID();
    public void setID(int id);
}

关于java - 模拟方法间依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1587193/

相关文章:

unit-testing - 是否可以模拟并忽略属性

java - 使用 mySQL 和 php 强制关闭 android 中的注册 Activity

java - 如何使用 Spring Security 的新 PasswordEncoder

使用内部对象进行 Java 单元测试

unit-testing - 如何为需要引用“静态生命周期并实现同步”的函数提供模拟值?

PHPUnit 将模拟对象作为参数传递给另一个对象的构造函数并使用 expects() 方法

java - react native Android 语法错误 : Attempted to redefine property 'key'

java - Teradata 和 Apache Kafka 使用 Kafka 连接

javascript - 如何模拟由 ember 的 IoC 注入(inject)的属性

java - @Mocked、@Injectable 和@Capturing 之间有什么区别?