Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito接口的Mocking getter/setter方法_Java_Junit_Mockito - Fatal编程技术网

Java Mockito接口的Mocking getter/setter方法

Java Mockito接口的Mocking getter/setter方法,java,junit,mockito,Java,Junit,Mockito,我试图用jUnit和Mockito测试我的实现,但我遇到了问题。下面是一个非常简单的例子来解释这个问题 接口KeyValueInterface public interface KeyValueInterface { public abstract String getKey(); public abstract void setKey(String key); public abstract String getValue(); public abstr

我试图用jUnit和Mockito测试我的实现,但我遇到了问题。下面是一个非常简单的例子来解释这个问题

接口KeyValueInterface

public interface KeyValueInterface {

    public abstract String getKey();

    public abstract void setKey(String key);

    public abstract String getValue();

    public abstract void setValue(String value);

}
类KeyValueImpl

public class KeyValueImpl implements KeyValueInterface {

    private String key;
    private String value;

    @Override
    public String getKey() {
        return key;
    }

    @Override
    public void setKey(String key) {
        this.key = key;
    }

    @Override
    public String getValue() {
        return value;
    }

    @Override
    public void setValue(String value) {
        this.value = value;
    }

}
使用“业务逻辑”初始化

jUnit测试类

import static org.junit.Assert.*;

import org.junit.Test;
import org.mockito.Mockito;

public class ValueFinderTest {

    @Test
    public void testNotMocked() {
        KeyValueInterface keyValue = new KeyValueImpl();
        keyValue = (new ValueFinder()).findValueForKey(keyValue);
        assertEquals("foo", keyValue.getValue()); // works fine
    }

    @Test
    public void testMocked1() {
        KeyValueInterface keyValue = Mockito.mock(KeyValueInterface.class);
        keyValue = (new ValueFinder()).findValueForKey(keyValue);
        assertEquals("foo", keyValue.getValue()); // java.lang.AssertionError:
                                                    // expected:<foo> but
                                                    // was:<null>

    }

    @Test
    public void testMocked2() {
        KeyValueInterface keyValue = Mockito.mock(KeyValueInterface.class);
        keyValue = (new ValueFinder()).findValueForKey(keyValue);
        Mockito.when(keyValue.getValue()).thenCallRealMethod();
        Mockito.doCallRealMethod().when(keyValue).setValue(Mockito.any(String.class));
        assertEquals("foo", keyValue.getValue()); // org.mockito.exceptions.base.MockitoException:
                                                    // Cannot call real method
                                                    // on java interface.
                                                    // Interface does not have
                                                    // any implementation!
                                                    // Calling real methods is
                                                    // only possible when
                                                    // mocking concrete classes.

    }

}
import static org.junit.Assert.*;
导入org.junit.Test;
导入org.mockito.mockito;
公共类ValueFinderTest{
@试验
public void testNotMocked(){
KeyValueInterface keyValue=新的KeyValueImpl();
keyValue=(新的ValueFinder()).findValueForKey(keyValue);
assertEquals(“foo”,keyValue.getValue());//工作正常
}
@试验
public void testMocked1(){
KeyValueInterface keyValue=Mockito.mock(KeyValueInterface.class);
keyValue=(新的ValueFinder()).findValueForKey(keyValue);
assertEquals(“foo”,keyValue.getValue());//java.lang.AssertionError:
//预期:但是
//是:
}
@试验
public void testMocked2(){
KeyValueInterface keyValue=Mockito.mock(KeyValueInterface.class);
keyValue=(新的ValueFinder()).findValueForKey(keyValue);
Mockito.when(keyValue.getValue()).thenCallRealMethod();
Mockito.doCallRealMethod().when(keyValue).setValue(Mockito.any(String.class));
assertEquals(“foo”,keyValue.getValue());//org.mockito.exceptions.base.MockitoException:
//无法调用实方法
//在java接口上。
//接口没有
//任何实现!
//调用真正的方法是非常困难的
//只有在
//模拟混凝土类。
}
}
我的问题是,出于我无法控制的技术原因,我需要模拟KeyValue。因此,我不能只使用testnotmock()方法。此外,由于我无法控制的技术原因,我不得不模拟接口(而不是类)

有没有办法做到这一点


非常感谢。

Mock对您的Impl类一无所知。因此,只需对
setValue
执行
verify
,或者使用spy调用real方法。

如果您要编写所测试方法的javadoc,甚至不知道接口的任何方法在做什么,您将编写以下内容:

/**
 * Sets "foo" as the value of the given keyValue, and returns it
 */
您甚至不应该假设
getValue()
返回以前设置的值。这当然不是mock将要做的,因为mock只做您让它做的事情。您所要做的就是测试方法的契约,而不必假设任何关于接口实现的内容。所以你的测试应该是

@Test
public void testMocked1() {
    KeyValueInterface keyValue = Mockito.mock(KeyValueInterface.class);
    KeyValueInterface result = (new ValueFinder()).findValueForKey(keyValue);

    // tests that the value has been set to "foo"
    verify(keyValue).setValue("foo");

    // tests that the method returns its argument
    assertSame(keyValue, result);
}

如果您检查下面mock方法的mockitoapi,您可以看到它创建了给定类或接口的mock对象

public static <T> T mock(java.lang.Class<T> classToMock)
并在方法testMocked1()中执行以下操作


类似地,对于第二个方法testMocked2(),也可以使用reflectionutils设置值,并使用Mockito中的任何api方法使用when/then配置模拟。
请参见

谢谢,您是指来自Spring框架的ReflectionTestUtils吗?
public static <T> T mock(java.lang.Class<T> classToMock)
ReflectionTestUtils.setField(classObject, key,keyvalue); 
assertEquals("foo", keyValue.getValue());