模拟静态默认接口方法

时间:2017-06-22 13:14:05

标签: java junit mockito powermock powermockito

我需要为以下情况创建一个单元测试:

待测班级:

class MyProducer {

private Producer producer = null;
private ProducerCreator producerCreator = null;

public MyProducer() {
 producerCreator = ProducerCreator.create(string name);
 producer = producerCreator.createProducer();

}
public boolean foo() {
  return producer.foo();
}
}

类ProducerCreator来自外部包,没有源代码:

public interface ProducerCreator {

static default ProducerCreator create(String name) {
  return new ProducerCreatorImpl(...)
  }
 }

所以我试图用PowerMockito来模拟静态调用:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ProducerCreator.class)
public class ProducerTest {

    @Test
    public void fooTest() {


        ProducerCreator producerCreatorMock = Mockito.mock(ProducerCreator.class);

 PowerMockito.mockStatic(ProducerCreator.class); 
 PowerMockito.when(ProducerCreator.class, "createProducer", "name").thenReturn(producerCreatorMock);

(也试过这个:

PowerMockito.when(ProducerCreator.create("name")).thenReturn(producerCreatorMock);

但它没有做任何改变)

        MyProducer myProducer = new MyProducer();


    assertTrue(myProducer.foo());



}

通常我会得到以下内容:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
...
E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

或任何其他错误或不需要的行为,而不是正确的模拟。 问题是由于界面中的“静态默认”方法吗? 在互联网上没有找到这种情况的任何例子。

UPD: 我不能分享真正的代码,因为它是专有的。

来自编译的外部包有一个真正的静态默认方法:

public interface ProducerCreator extends Closeable {
    static default ProducerCreator create(String serviceUrl) throws ProducerCreatorException {
        return ...
    }

UPD 2:包是一个JNI包 - 从CPP代码生成..

1 个答案:

答案 0 :(得分:0)

您的代码无法编译。我做了一些假设:

public class Producer {
    public boolean foo(){
        return true;
    }
}

public interface ProducerCreator {
    public static ProducerCreator create(String name) {
        return new ProducerCreatorImpl(name);
    }

    Producer  createProducer();
}

public class MyProducer {

    private Producer producer = null;
    private ProducerCreator producerCreator = null;

    public MyProducer() {
        producerCreator = create("name");
        producer = producerCreator.createProducer();

    }
    public boolean foo() {
        return producer.foo();
    }
}
public class ProducerCreatorImpl implements ProducerCreator{


    public ProducerCreatorImpl(String name) {

    }

    @Override
    public Producer createProducer() {
        return new Producer();
    }
}

你的测试,对我有用:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ProducerCreator.class })
public class DatasourceTest {

    @Test
    public void fooTest() {


        ProducerCreator producerCreatorMock = Mockito.mock(ProducerCreator.class);

        PowerMockito.mockStatic(ProducerCreator.class);
        PowerMockito.when(ProducerCreator.create(Mockito.anyString())).thenReturn(producerCreatorMock);

        Producer prodMock = Mockito.mock(Producer.class);
        Mockito.when(producerCreatorMock.createProducer()).thenReturn(prodMock);
        Mockito.when(prodMock.foo()).thenReturn(false);

        MyProducer myProducer = new MyProducer();
        boolean result = myProducer.foo();

        Assert.assertFalse(result);

        Mockito.verify(prodMock).foo();

    }
}