Java 如何使JMockit向JMockit@Tested类注入特定实例?

Java 如何使JMockit向JMockit@Tested类注入特定实例?,java,jmockit,Java,Jmockit,我有一个类,我正试图用JMockit1.49测试它。我的被测类使用带有2个参数的构造函数注入;一个是模拟的,另一个是我想在测试类中实例化并让JMockit为我注入的。不幸的是,我似乎无法让这个工作 public class DocFilterService { // get a static slf4j logger for the class protected static final Logger logger = getLogger(DocFilterService.c

我有一个类,我正试图用JMockit1.49测试它。我的被测类使用带有2个参数的构造函数注入;一个是模拟的,另一个是我想在测试类中实例化并让JMockit为我注入的。不幸的是,我似乎无法让这个工作

public class DocFilterService {

    // get a static slf4j logger for the class
    protected static final Logger logger = getLogger(DocFilterService.class);

    private DocRepository DocRepository;
    private ObjectMapper objectMapper;

    @Inject
    public DocFilterService(DocRepository DocRepository, @Doc ObjectMapper objectMapper) {
        this.DocRepository = DocRepository;
        this.objectMapper = objectMapper;
    }

    // business method to test
    public DocWrapperDTO filterDoc(Context context, DocWrapperDTO dcfData){
      // some business logic looking to test.
      ... 
    }
}
在我的JMockit测试类中,我有以下内容:

public class DocFilterServiceTest2 {

    @Mocked @Injectable DocRepository DocRepository;
    @Doc ObjectMapper objectMapper = new DocProducer().getMapper();
    @Tested DocFilterService sut;

    @BeforeClass
    public static void jMockit(){
        Startup.verifyInitialization();
    }

    @Test
    public void testInvalidResponse() throws IOException {
        // create some valid input
        Context context = Context.ContextBuilder.aContext()
                .user(User.UserBuilder.aUser()
                        .id("123")
                        .build()
                )
                .build();

        ObjectMapper mapper = new ObjectMapper();
        new Expectations(){{
            DocRepository.filterDoc( (Body<DocWrapperDTO>) any ); result = mapper.readTree("{\"decision_id\": \"1\"}"); minTimes=1;
        }};


        // todo to fix.  Use a Mock repo and proper parameter
        sut.filterDoc( context, new DocWrapperDTO());

        new Verifications(){{
            DocRepository.filterDoc((Body<DocWrapperDTO>)any);
        }};

    }
}
如果我将
@Tested
注释更改为

        @Tested(fullyInitialized=true) DocFilterService sut;
然后,注入my
sut
ObjectMapper
是ObjectMapper的一个新实例,而不是声明为
@Doc ObjectMapper ObjectMapper=new DocProducer().getMapper()的实例实例

我试着阅读JMockit上的文档,我觉得它应该使用测试类中声明的任何实例,但它似乎没有这样做


我如何向JMockit指定/声明我希望它使用我的实例作为注入候选,而不是实例化一个新实例?我是否需要将其声明为已测试的
@Tested
实例?它似乎不是正确的注释。

对于@Tested元素,JMockit将调用一个具有@Injectable参数的构造。在您的情况下,您需要将DocRepository和ObjectMapper都设置为@Injectable。默认情况下,@Injectables也是@mock的,因此不需要两个注释。我相信这会奏效

@Injectable DocRepository DocRepository;
@Injectable ObjectMapper objectMapper;
@Tested DocFilterService sut;

也就是说,上面的内容使objectMapper成为一个模拟对象。您的原始代码似乎试图使用它的真实实例。纯粹地说,这是一个坏主意,因为ObjectMapper是一个不同的“单元”,所以在DocFilterService“单元”中,我们应该将其视为一个黑盒并对其进行模拟。

对于@Tested元素,JMockit将调用一个具有@Injectable参数的构造。在您的情况下,您需要将DocRepository和ObjectMapper都设置为@Injectable。默认情况下,@Injectables也是@mock的,因此不需要两个注释。我相信这会奏效

@Injectable DocRepository DocRepository;
@Injectable ObjectMapper objectMapper;
@Tested DocFilterService sut;

也就是说,上面的内容使objectMapper成为一个模拟对象。您的原始代码似乎试图使用它的真实实例。纯粹地说,这是一个坏主意,因为ObjectMapper是一个不同的“单元”,所以在DocFilterService的“单元”中,我们应该将其视为一个黑盒并对其进行模拟。

我甚至尝试通过使用模拟来解决这个问题,为某些类提供一个“自定义”实现,同时仍然让JMockit认为它是一个可注入的模拟。但是,这似乎也不受支持。看来你在这里运气不好。也许您可以尝试DocFilterService的一个子类,它有自己的构造函数,只公开需要模拟/注入的字段。它可能只是测试文件中的一个静态嵌套类。Hacky,当然,但从技术上讲,它测试的是相同的代码,同时仍然允许您使用
new DocProducer().getMapper()
。我甚至尝试通过使用模型来解决这个问题,为某些类提供一个“自定义”实现,同时仍然让JMockit认为它是一个可注入的模型。但是,这似乎也不受支持。看来你在这里运气不好。也许您可以尝试DocFilterService的一个子类,它有自己的构造函数,只公开需要模拟/注入的字段。它可能只是测试文件中的一个静态嵌套类。Hacky,当然,但从技术上讲,它正在测试相同的代码,同时仍然允许您使用
newdocproducer().getMapper()