Java JMockit:如何设置可注射的属性?

Java JMockit:如何设置可注射的属性?,java,jmockit,Java,Jmockit,考虑以下代码: @Tested CodeToTest codeToTest; @Injectable Injected injected; @Test public void test() { new Expectations() {{ ... }} assertThat(codeToTest.memberVariable).isEqualTo("x"); } // public class CodeToTest { public CodeToTest(Injected inje

考虑以下代码:

@Tested
CodeToTest codeToTest;

@Injectable
Injected injected;

@Test
public void test() {
  new Expectations() {{ ... }}
  assertThat(codeToTest.memberVariable).isEqualTo("x");
}

//

public class CodeToTest { public CodeToTest(Injected injected) { memberVariable = injected.getProperty("x") } }

我想测试CodeToTest。CodeToTest需要注入到它的构造函数中。如何设置一个属性,例如injected.setProperty(“x”),以便在CodeToTest中可以访问它?

手头的测试应该包括
CodeToTest
的特定方法;构造函数应该像您的测试一样拥有自己的测试。例如,如果构造函数根据传入的内容设置字段,如下所示:

public class Bar {
    public int getValue() {
        return 8675309;
    }
}

public class Foo {
    public String field = null;

    public Foo(Bar b) {
        this.field = "" + b.getValue();
    }

    public String getField() {
        return this.field;
    }

    public char getFirstChar() {
        return getField().charAt(0);
    }
}
在这里,我根据传递给构造函数的
条中的
int
设置
字符串
字段。我希望对我的
getFirstChar()
方法进行单元测试

@Tested Foo foo;

@Injectable Bar bar;

@Test
public void test() throws Exception {
// ...
}
现在,正如您所指出的,在本例中,我的
字段在
test()
甚至开始之前就已经设置好了。因此,这里我有两个选择:首先,由于我根据其getter拉出
字段
,我可以部分模拟正在测试的类:

@Test
public void test() throws Exception {
    new Expectations(foo) {{
        foo.getField(); result = "24601";
    }};

    char c = foo.getFirstChar();

    assertThat(c, is('2'));
}
或者,如果您不想这样做,或者您正在进行直接字段访问而不是通过getter,则可以使用
Deencapsulation
(JMockit的一部分)设置内部字段,然后测试:

@Test
public void test() throws Exception {
    Deencapsulation.setField(foo, "field", "24601");

    char c = foo.getFirstChar();

    assertThat(c, is('2'));
}
当然,我会单独测试我的构造函数:

@Test
public void testConstructor() throws Exception {
    new Expectations() {{
        bar.getValue(); result = 24601;
    }};

    Foo foo2 = new Foo(bar);
    String fieldValue = foo2.getField(); // or use Deencapsulation
    assertThat(fieldValue, is("24601"));
}

希望这有帮助,祝你好运

这对我不起作用:我的CodeToTest构造函数依赖于在注入对象上设置的属性,以便无错误地实例化@测试对象在满足期望块之前被实例化。(顺便说一句,我已经阅读了文档,但发现它在很多方面都有欠缺)我认为在这种情况下基本上我不能使用Tested和Injectable,我需要在testI下手动构建我的对象,很抱歉我误解了您最初的问题。。。单元测试应该只测试手边的方法。您的构造函数应该有自己的单元测试,并且手头的方法(
CodeToTest.getMemberVariable()
或其他)应该有自己的测试。。。是的,构造函数中设置的任何字段都应该注入
Deencapsulation
。让我用一些插图更新我的答案…好的,我更新了我的答案-有点长,但希望它是有用的。