JMockIt Mock 未使用 Faking 应用:Mocking parents of mocked 类
JMockIt Mock not being applied using Faking : Mocking parents of mocked classes
好的...我有一个答案...见下文。感谢所有提供帮助的人。我也更新了标题以更好地反映问题。
UPDATE2:正在使用空参数调用 ClassNotUnderTest(具有参数)的 parent class 的构造函数,后者又使用相同的空参数调用它的 parent ,最终导致空异常。
我试过:
模拟两个 parents,只有构造函数模拟并在尝试测试时使用其中一个或两个。 MockClassNotUnderTest 仍然调用真正的构造函数。
我尝试在测试方法的参数列表中使用 @Mocked 注释,因为我真的不想从那些 parents 返回任何东西......不。导致其他一些我不明白的错误。
我尝试在我的 $init 函数中调用 super(someParams),但无法编译。
HEEEEELLLLLPPPPP!!!!
更新:
好的,我的问题的根源不是如下所示的实现,而是模拟本身。当 MockClassNotUnderTest 调用它的构造函数时,它正在调用 ClassNotUnderTest 的真实 parent 的构造函数。我也试过嘲笑 ParentofClassNotUnderTest,但这只是导致了 NullPointerExceptions ......叹息。仍在搜索中,我会 post 及时更新。欢迎提出任何建议。
我是 JMockIt 的新手,但我的 Java 技能还不错。我正在尝试模拟被测 class 的依赖项 class。似乎正在调用真正的方法,或者它可能是超级 class (更有可能)。那么对我做错了什么有什么想法吗?
现在我知道有些人可能会评论我如何设置错误参数,以及如何应用等等,我欢迎评论,但主要问题是这段代码没有被模拟 properly/at 尽我所能。
预先回答几个问题...是的,我在这里搜索过,是的,我在 JMockIt 网站上查看了 tutorials/documentation...在我首先编写代码时都打开了。
我有几个类似的情况需要解决,所以非常感谢您的帮助。提前致谢。
像这样:
public ClassUnderTest {
public someMethodUnderTest (){
<blah blah setup stuff>
try{
somevar = new ClassNotUnderTest(someParamA, someParamB, someParamC);
} catch(SomeExceptionA sea) {
System.out.printline("Go boom");
} <more catches here>
}
}
我的test/mockclass如下(JUnit4/JMockIt):
public class TestClassUnderTest{
ClassUnderTest cut;
<Before method and constructor with some setup code for cut>
@Test public void test_someMethodUnderTest(){
MockClassNotUnderTest notUnderTest = new MockClassNotUnderTest();
notUnderTest.error = 1;
try{
testResults = cut.someMethodUnderTest();
} catch( SomeExceptionA sea) {
<test that it went boom>
}
}
public class MockClassNotUnderTest extends MockUp<ClassNotUnderTest> {
public int error = 4;
@Mock
public void $init(someParamA, someParamB, someParamC) throws SomeExceptionA, SomeExceptionB, SomeExceptionC {
if(error == 0) { thrown new SomeExeptionA(); }
else if(error == 1) { thrown new SomeExeptionB(); }
else if(error == 2) { thrown new SomeExeptionC(); }
else { }
}
}
}
我的期望是您在测试方法中初始化的 new MockClassNotUnderTest()
不 与 new ClassNotUnderTest()
共享状态您正在生产代码中进行初始化。
尝试将您的 error
设为 static
字段,以便在被伪造的对象之间共享。
我已经编写了一个示例测试用例,表明您在下面的评论是正确的。除非你 post 真正的代码,否则我无法复制你的问题...这是我的测试:
public class FakeTest {
public static class Foo {
public void doSomething() {
try {
Bar b = new Bar(73);
} catch (Throwable t) {
System.out.println("Got a " + t.getClass());
}
}
}
public static class Bar {
private Integer param;
public Bar(Integer parameter) {
System.out.println("Got a real bar with param " + parameter);
this.param = parameter;
}
}
public static class MockBar extends MockUp<Bar> {
public int error = 4;
@Mock
public void $init(Integer parameter) {
System.out.println("Initing fake with parameter " + parameter);
if (error==1) {
throw new IllegalAccessError();
}
}
}
@Test
public void fakeTest() throws Exception {
System.out.println("Testing...");
MockBar mb = new MockBar();
mb.error=1;
Foo f = new Foo();
f.doSomething();
}
}
如您所料,输出是
Testing...
Initing fake with parameter 73
Got a class java.lang.IllegalAccessError
将此视为上述答案的第二部分。
那里提供的内容将成功地模拟出一个构造函数。我的问题的根源在于我原来的 MockClassNotUnderTest 正在调用 ClassNotUnderTest 的 REAL 父类的构造函数。伪造这并不是完全出乎意料的,所以我模拟了父对象......模拟从未调用过。
我最初的模拟设置(上面的 MockBar mb = new MockBar())会在其上方有一行来设置父模拟,它看起来完全一样,但名称不同。所以我可能有:
MockBarParent mbp = new MockBarParent();
MockBar mb = new MockBar();
mb.error = 1;
这显然行不通...这是行之有效的方法:
Mockit.setUpMock(new MockBarParent());
MockBar mb = new MockBar();
mb.error = 1;
至于为什么,我不确定,但我可以告诉你这是设置静态模拟的方式。
最后一句话。当您执行此操作时,这些模拟将保留在内存中。在离开测试函数之前一定要调用 Mockit.tearDownMocks() 否则它会持续到其他测试中。 JUnit 没有按顺序 运行 测试,所以这会导致各种有趣的错误。
再次感谢您的帮助!!!! @dcsohl 和尼古拉斯
好的...我有一个答案...见下文。感谢所有提供帮助的人。我也更新了标题以更好地反映问题。
UPDATE2:正在使用空参数调用 ClassNotUnderTest(具有参数)的 parent class 的构造函数,后者又使用相同的空参数调用它的 parent ,最终导致空异常。
我试过:
模拟两个 parents,只有构造函数模拟并在尝试测试时使用其中一个或两个。 MockClassNotUnderTest 仍然调用真正的构造函数。
我尝试在测试方法的参数列表中使用 @Mocked 注释,因为我真的不想从那些 parents 返回任何东西......不。导致其他一些我不明白的错误。
我尝试在我的 $init 函数中调用 super(someParams),但无法编译。
HEEEEELLLLLPPPPP!!!!
更新:
好的,我的问题的根源不是如下所示的实现,而是模拟本身。当 MockClassNotUnderTest 调用它的构造函数时,它正在调用 ClassNotUnderTest 的真实 parent 的构造函数。我也试过嘲笑 ParentofClassNotUnderTest,但这只是导致了 NullPointerExceptions ......叹息。仍在搜索中,我会 post 及时更新。欢迎提出任何建议。
我是 JMockIt 的新手,但我的 Java 技能还不错。我正在尝试模拟被测 class 的依赖项 class。似乎正在调用真正的方法,或者它可能是超级 class (更有可能)。那么对我做错了什么有什么想法吗?
现在我知道有些人可能会评论我如何设置错误参数,以及如何应用等等,我欢迎评论,但主要问题是这段代码没有被模拟 properly/at 尽我所能。
预先回答几个问题...是的,我在这里搜索过,是的,我在 JMockIt 网站上查看了 tutorials/documentation...在我首先编写代码时都打开了。
我有几个类似的情况需要解决,所以非常感谢您的帮助。提前致谢。
像这样:
public ClassUnderTest {
public someMethodUnderTest (){
<blah blah setup stuff>
try{
somevar = new ClassNotUnderTest(someParamA, someParamB, someParamC);
} catch(SomeExceptionA sea) {
System.out.printline("Go boom");
} <more catches here>
}
}
我的test/mockclass如下(JUnit4/JMockIt):
public class TestClassUnderTest{
ClassUnderTest cut;
<Before method and constructor with some setup code for cut>
@Test public void test_someMethodUnderTest(){
MockClassNotUnderTest notUnderTest = new MockClassNotUnderTest();
notUnderTest.error = 1;
try{
testResults = cut.someMethodUnderTest();
} catch( SomeExceptionA sea) {
<test that it went boom>
}
}
public class MockClassNotUnderTest extends MockUp<ClassNotUnderTest> {
public int error = 4;
@Mock
public void $init(someParamA, someParamB, someParamC) throws SomeExceptionA, SomeExceptionB, SomeExceptionC {
if(error == 0) { thrown new SomeExeptionA(); }
else if(error == 1) { thrown new SomeExeptionB(); }
else if(error == 2) { thrown new SomeExeptionC(); }
else { }
}
}
}
我的期望是您在测试方法中初始化的 new MockClassNotUnderTest()
不 与 new ClassNotUnderTest()
共享状态您正在生产代码中进行初始化。
尝试将您的 error
设为 static
字段,以便在被伪造的对象之间共享。
我已经编写了一个示例测试用例,表明您在下面的评论是正确的。除非你 post 真正的代码,否则我无法复制你的问题...这是我的测试:
public class FakeTest {
public static class Foo {
public void doSomething() {
try {
Bar b = new Bar(73);
} catch (Throwable t) {
System.out.println("Got a " + t.getClass());
}
}
}
public static class Bar {
private Integer param;
public Bar(Integer parameter) {
System.out.println("Got a real bar with param " + parameter);
this.param = parameter;
}
}
public static class MockBar extends MockUp<Bar> {
public int error = 4;
@Mock
public void $init(Integer parameter) {
System.out.println("Initing fake with parameter " + parameter);
if (error==1) {
throw new IllegalAccessError();
}
}
}
@Test
public void fakeTest() throws Exception {
System.out.println("Testing...");
MockBar mb = new MockBar();
mb.error=1;
Foo f = new Foo();
f.doSomething();
}
}
如您所料,输出是
Testing...
Initing fake with parameter 73
Got a class java.lang.IllegalAccessError
将此视为上述答案的第二部分。
那里提供的内容将成功地模拟出一个构造函数。我的问题的根源在于我原来的 MockClassNotUnderTest 正在调用 ClassNotUnderTest 的 REAL 父类的构造函数。伪造这并不是完全出乎意料的,所以我模拟了父对象......模拟从未调用过。
我最初的模拟设置(上面的 MockBar mb = new MockBar())会在其上方有一行来设置父模拟,它看起来完全一样,但名称不同。所以我可能有:
MockBarParent mbp = new MockBarParent();
MockBar mb = new MockBar();
mb.error = 1;
这显然行不通...这是行之有效的方法:
Mockit.setUpMock(new MockBarParent());
MockBar mb = new MockBar();
mb.error = 1;
至于为什么,我不确定,但我可以告诉你这是设置静态模拟的方式。
最后一句话。当您执行此操作时,这些模拟将保留在内存中。在离开测试函数之前一定要调用 Mockit.tearDownMocks() 否则它会持续到其他测试中。 JUnit 没有按顺序 运行 测试,所以这会导致各种有趣的错误。
再次感谢您的帮助!!!! @dcsohl 和尼古拉斯