Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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 模拟抽象方法,但不模拟类构造函数_Java_Unit Testing_Mockito - Fatal编程技术网

Java 模拟抽象方法,但不模拟类构造函数

Java 模拟抽象方法,但不模拟类构造函数,java,unit-testing,mockito,Java,Unit Testing,Mockito,我有一个场景,其中我有一个类似于下面的抽象类。我想模拟通过构造函数提供的RandomNumberGenerator实例,并编写一个单元测试来测试doSomethingRandomLotsOfTimes方法中的逻辑 有没有一种方法可以用mockito/另一个框架实现这一点 public abstract class MyClass { private final RandomNumberGenerator randomNumberGenerator; public MyClas

我有一个场景,其中我有一个类似于下面的抽象类。我想模拟通过构造函数提供的
RandomNumberGenerator
实例,并编写一个单元测试来测试
doSomethingRandomLotsOfTimes
方法中的逻辑

有没有一种方法可以用mockito/另一个框架实现这一点

public abstract class MyClass {

    private final RandomNumberGenerator randomNumberGenerator;

    public MyClass(RandomNumberGenerator randomNumberGenerator) {
        this.randomNumberGenerator = randomNumberGenerator;
    }

    public abstract void doSomething(int x);

    public void doSomethingRandomLotsOfTimes() {
        for(int i=0; i<10; i++) {
            int r = randomNumberGenerator.next();
            doSomething(r);
        }
    }
}

无法直接实例化抽象类。 必须实例化扩展抽象类的非抽象类

声明一个非抽象类,该类扩展单元测试类中的抽象类(例如
公共静态类blam extends MyClass
),并提供所有抽象方法的空实现

一旦你有了一个可以实例化的类, 创建RandomNumberGenerator类的间谍。 spy允许您测试spy中的方法是否被调用


创建
blam
的实例,并将spy RandomNumberGenerator作为构造函数参数传递。

无法直接实例化抽象类。 必须实例化扩展抽象类的非抽象类

声明一个非抽象类,该类扩展单元测试类中的抽象类(例如
公共静态类blam extends MyClass
),并提供所有抽象方法的空实现

一旦你有了一个可以实例化的类, 创建RandomNumberGenerator类的间谍。 spy允许您测试spy中的方法是否被调用


创建
bum
的实例,并将spy RandomNumberGenerator作为构造函数参数传递。

您的类更容易通过组合实现:

public final class MyClass {

    private final RandomNumberGenerator randomNumberGenerator;
    private final IntConsumer somethingDoer;

    public MyClass(
            RandomNumberGenerator randomNumberGenerator,
            IntConsumer somethingDoer) {
        this.randomNumberGenerator = randomNumberGenerator;
        this.somethingDoer = somethingDoer;
    }

    public void doSomethingRandomLotsOfTimes() {
        for(int i=0; i<10; i++) {
            int r = randomNumberGenerator.next();
            somethingDoer.consume(r);
        }
    }
}
公共最终类MyClass{
私人最终RandomNumberGenerator RandomNumberGenerator;
私人最终消费者或某些行为人;
公共MyClass(
RandomNumberGenerator RandomNumberGenerator,
IntConsumer something doer){
this.randomNumberGenerator=randomNumberGenerator;
this.somethingDoer=somethingDoer;
}
公共无效dosomethin grandomlotsoftimes(){

对于(int i=0;i,您的类更容易通过组合实现:

public final class MyClass {

    private final RandomNumberGenerator randomNumberGenerator;
    private final IntConsumer somethingDoer;

    public MyClass(
            RandomNumberGenerator randomNumberGenerator,
            IntConsumer somethingDoer) {
        this.randomNumberGenerator = randomNumberGenerator;
        this.somethingDoer = somethingDoer;
    }

    public void doSomethingRandomLotsOfTimes() {
        for(int i=0; i<10; i++) {
            int r = randomNumberGenerator.next();
            somethingDoer.consume(r);
        }
    }
}
公共最终类MyClass{
私人最终RandomNumberGenerator RandomNumberGenerator;
私人最终消费者或某些行为人;
公共MyClass(
RandomNumberGenerator RandomNumberGenerator,
IntConsumer something doer){
this.randomNumberGenerator=randomNumberGenerator;
this.somethingDoer=somethingDoer;
}
公共无效dosomethin grandomlotsoftimes(){

对于(int i=0;i@OleksandrShpota我认为这是一个不同的问题,因为这些问题不涉及需要模拟的构造函数参数。为什么需要模拟这个类?使用真实的类,使用模拟的RNG。此外,这看起来像是一个组合应该优先于继承的示例:
doSomething
只是一个:传递然后你可以对
IntConsumer
进行单元测试,
MyClass
调用
IntConsumer
的单元测试。我宁愿把这个类中特定于逻辑的测试放在
MyClassTest
中,让子类的测试只考虑它们自身的逻辑“我宁愿在这个类中保留特定于逻辑的测试"这就支持了Andy对合成优于继承的建议。让它成为一个真正的类,给方法
doSomethingRandomLotsOfTimes
一个函数接口参数,并将其作为依赖项传递给需要它的类。@OleksandrShpota我认为这是有区别的,因为这些问题不涉及构造函数参数要模拟的ds为什么需要模拟此类?使用带有模拟RNG的真实类。此外,这似乎是一个组合优先于继承的示例:
doSomething
只是一个:将其中一个传递到构造函数中。然后可以对
IntConsumer
进行单元测试,并对
MyC进行单元测试lass
调用
IntConsumer
。我宁愿将此类中特定于逻辑的测试保留在
MyClassTest
中,而让子类的测试只关心其自身的逻辑“我宁愿将特定于逻辑的测试保留在此类中”这就支持了Andy关于组合优于继承的建议。将thid作为一个真正的类,给方法
doSomethingRandomLotsOfTimes
一个函数接口参数,并将其作为依赖项传递给需要它的类。我很想测试MyClass中的逻辑如何处理doSomething()的一些场景抛出异常等,您描述的方法是否可能?@Ed0906当然,只需实现抽象方法来抛出异常。您可以使用以下方法创建模拟:
MyClass MyClass=mock(MyClass.class,Mockito.CALLS_REAL_METHODS);
来抛出异常:
doThrow(new exception()).when(MyClass.doSomething(anyInt())
一旦你有了spy,它与Hugo提到的模拟调用_Real_方法完全一样。有了spy,你可以模拟单个方法并根据需要抛出。我很想测试一些场景,看看MyClass中的逻辑如何处理doSomething()抛出异常等,您描述的方法是否可能?@Ed0906当然,只需实现抽象方法来抛出异常。您可以使用以下方法创建模拟:
MyClass MyClass=mock(MyClass.class,Mockito.CALLS_REAL_METHODS);
来抛出异常:
doThrow(new exception()).when(MyClass.doSomething(anyInt())
一旦你有了间谍,这与雨果提到的模拟呼叫和真实方法完全一样。有了间谍,你可以模拟单独的方法并根据需要投掷。非常感谢你,先生——祝你晚上愉快,晚安,并愿接下来的几天用伟大的问题来回答你!非常感谢,先生