java Mockito:如何测试构造函数被调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38847558/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:49:16  来源:igfitidea点击:

Mockito: how to test that a constructor was called?

javaconstructormockingmockito

提问by java123999

I am using Mockito to test methods within my Java application.

我正在使用 Mockito 来测试我的 Java 应用程序中的方法。

How can I test that a constructor was called once?

如何测试构造函数是否被调用过一次?

I am trying to do a verification similar to this:

我正在尝试进行类似于此的验证:

verify(myClass, times(1)).doSomething(anotherObject);

But I can't verify that the constructor was called as it doesn't have a method similar to e.g. doSomething().

但是我无法验证构造函数是否被调用,因为它没有类似于 eg 的方法doSomething()

回答by Jose Tepedino

You can do it with Mockito and PowerMockito.

你可以用 Mockito 和 PowerMockito 做到这一点。

Say you have ClassUnderTest with a constructor

假设你有一个带有构造函数的 ClassUnderTest

public class ClassUnderTest {
    String name;
    boolean condition;

    public ClassUnderTest(String name, boolean condition) {
       this.name = name;
       this.condition = condition;
       init();
    }

    ...
}

And another class that calls that constructor

另一个调用该构造函数的类

public class MyClass {

    public MyClass() { } 

    public void createCUTInstance() {
       // ...
       ClassUnderTest cut = new ClassUnderTest("abc", true);
       // ...
    }

    ...
}

At the Test class we could...

在测试课上,我们可以...

(1) use PowerMockRunner and cite both target classes above in the PrepareForTest annotation:

(1) 使用 PowerMockRunner 并在 PrepareForTest 注释中引用上面的两个目标类:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ClassUnderTest.class, MyClass.class })
public class TestClass {

(2) intercept the constructor to return a mock object:

(2)拦截构造函数返回一个mock对象:

@Before
public void setup() {
    ClassUnderTest cutMock = Mockito.mock(ClassUnderTest.class);
    PowerMockito.whenNew(ClassUnderTest.class)
                .withArguments(Matchers.anyString(), Matchers.anyBoolean())
                .thenReturn(cutMock);
}

(3) validate the constructor call:

(3) 验证构造函数调用:

@Test
public void testMethod() {
    // prepare
    MyClasss myClass = new MyClass();

    // execute
    myClass.createCUTInstance();

    // checks if the constructor has been called once and with the expected argument values:
    String name = "abc";
    String condition = true;
    PowerMockito.verifyNew(ClassUnderTest.class).withArguments(name, condition);
}

回答by StuPointerException

This can't be done with Mockito, since the object being created is not a mocked object. This also means that you won't be able to verify anything on that new object either.

Mockito 无法做到这一点,因为创建的对象不是模拟对象。这也意味着您也无法验证该新对象上的任何内容。

I've worked around this scenario in the past by using a Factoryto create the object rather than newing it up. You're then able to mock the Factoryto return the object required for your test.

过去我通过使用 aFactory创建对象而不是更新它来解决这个场景。然后,您可以模拟Factory返回测试所需的对象。

Whether you're happy changing your design to suit your tests is up to you!

您是否乐于更改设计以适合您的测试取决于您!

回答by Rudzianko?

verify()method waits for mocked object(already created object). And constructorcan not be called on created object.

verify()方法等待模拟对象(已经创建的对象)。并且constructor不能被调用created object

回答by vbuhlev

This is not possible with Mockito and sounds like a bad design.

这对于 Mockito 来说是不可能的,听起来像是一个糟糕的设计。

You can use a factory and pass it to the object under test. After that you can easily mock the factory and verify that its create method was called.

您可以使用工厂并将其传递给被测对象。之后,您可以轻松模拟工厂并验证其 create 方法是否被调用。

By directly creating objects in your code you are making a hard dependency to concrete implementations, which makes the code harder and sometimes impossible to unit test. This is addressed with Dependency Injection (DI) and Inversion of Control (IoC).

通过在代码中直接创建对象,您会严重依赖于具体的实现,这使得代码更难,有时甚至无法进行单元测试。这可以通过依赖注入 (DI) 和控制反转 (IoC) 解决。

回答by kuhajeyan

you will not be able to mock the constructor with mockito, but using powermockito you should be able to and then verify it. Setup would be something like this

您将无法使用 mockito 模拟构造函数,但使用 powermockito 您应该能够然后验证它。设置将是这样的

public class MyClass{

   public MyClass(String name){}

   public void doSomethingUseFul(){
      //.......
   }

}

public class Helper {

   public void goHelp(){
       new MyClass("apple").doSomethingUseFul();
   } 

}

//Mock

//嘲笑

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(MyClass.class)
    public class MockMyClass {
    @InjectMocks
    private Helper helper;

        @Test
        public void testDoSomethingUseFul() {
             MyClass  c = mock(MyClass.class); 
             doNothing().when(c).doSomethingUseFul();
             PowerMockito.whenNew(MyClass. class).withArguments(anyString()).thenReturn(c);
             helper.goHelp(); 
             verifyNew(MyClass.class).withArguments(anyString())


        }
    }

回答by Olian04

A constructor won't return an object if it failed... and if it fails the program will most likely crash.

如果失败,构造函数将不会返回对象……如果失败,程序很可能会崩溃。

Tough i suppose this would do it:

艰难我想这会做到:

Object obj = null;

obj = new Object();

if (obj == null) {
  //... Didn't Work
} else {
  //... Worked
}