简体   繁体   English

如何使用Mockito模拟通用方法?

[英]How to mock generic method using mockito?

I am trying to mock a generic method but getting class cast exception, no matter what I try. 我正在尝试模拟通用方法,但是无论我尝试如何,都会得到类强制转换异常。 Class under testing is 正在测试的课程是

public class TClass {
    private byte[] data;
    public <T extends SInterface> T asObject(T item){
        item.SMethod(this.getData());
        return item;
    }

    private byte[] getData() {
        return data;
    }
}

while the testing class is 测试班

@RunWith(MockitoJUnitRunner.class)
public class TClassTest {
    @Mock
    SSInterface sClass;
    @Mock
    SObject sObject;

    TClass tClass = new TClass();


    @org.junit.Before
    public void setUp() throws Exception {
    }

    @org.junit.Test
    public void asObject() {
        Mockito.when(tClass.asObject(new SSClass())).thenReturn(sClass);
    }
}

Other helper classes and interface are: 其他帮助程序类接口是:

 public interface SInterface {
    public void SMethod(byte[] in);
}



public interface SSInterface extends SInterface {
}


public class SSClass implements SSInterface {
    @Override
    public void SMethod(byte[] in) {
    }
}

public class SObject {
}

The error I am getting is : 我得到的错误是:

Cannot resolve method thenReturn(generic.SSInterface) 无法解析方法thenReturn(generic.SSInterface)

if I use Mockito.when(tClass.asObject(new SSClass())).thenReturn(new SSClass()); 如果我使用Mockito.when(tClass.asObject(new SSClass())).thenReturn(new SSClass());

I get org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. 我得到org.mockito.exceptions.misusing.MissingMethodInvocationException:when()需要一个参数,该参数必须是“模拟的方法调用”。 For example: when(mock.getArticles()).thenReturn(articles); 例如:when(mock.getArticles())。thenReturn(articles);

Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. 另外,可能会由于以下原因而出现此错误:1.您对以下方法之一进行存根:final / private / equals()/ hashCode()方法。 Those methods cannot be stubbed/verified. 这些方法不能存根/验证。 Mocking methods declared on non-public parent classes is not supported. 不支持在非公共父类上声明的模拟方法。 2. inside when() you don't call method on mock but on some other object. 2.在when()内部,您不会在模拟对象上调用方法,而是在其他某个对象上调用方法。

at generic.TClassTest.asObject(TClassTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:78)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:84)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

You have incompatible types and it has nothing to do with mockito. 您具有不兼容的类型,并且与模仿无关。 asObject() returns the same type as it receives and it has to be of SInterface type. asObject()返回与接收的类型相同的类型,并且必须为SInterface类型。

Depending on what you trying to achive ou can either return the instance of SSClasss : 根据您尝试达到的目标,可以返回SSClasss的实例:

Mockito.when(tClass.asObject(new SSClass())).thenReturn( new SSClass());

or you can make TClass extend SInterface and then: 或者您可以使TClass扩展SInterface ,然后:

Mockito.when(tClass.asObject(tClass)).thenReturn(tClass);

I think that you want to test TClass.asObject() but verifying sClass.SMethod() is called. 我认为您想测试TClass.asObject()但要调用sClass.SMethod()。

@org.junit.Test
public void asObject() {
        final SSInterface sut = new SSClass();

        final SSInterface returned = sut.asObject(sClass);

        assertEquals(sClass, returned);
        Mockito.verify(sClass).SMethod(any());    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM