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
Mockito: how to test that a constructor was called?
提问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 Factory
to create the object rather than newing it up. You're then able to mock the Factory
to 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 constructor
can 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
}