为什么@Injectable类上有NPE

时间:2014-10-31 21:54:26

标签: jmockit

我有一个班级(看起来像这样)我试图测试。

@Component
@Path("/user")
@Produces(MediaType.APPLICATION_JSON)
public class UserResource extends BaseResource {
    @Autowired UserService userService;

    @POST
    @Path("register")
    public User registerUser(User user){
        ...
        User registeredUser = userService.register(user);
        ...
        return registeredUser;
    }
}

测试看起来像这样。

public class UserResourceTest {
    @Tested UserResource userResource;
    @Injectable UserService userService;
    @Mocked BaseResource baseResource;

    @Test
    public void registerShouldDoSomething(){
        User user = new User();
        final User registerResult = new User();
        ...
        new NonStrictExpectations() {{
            userService.register((User)any); result = registerResult;
        }};
        userResource.registerUser(user);
        ...
    }
}

由于某些原因,在测试类中,userService为null并且在调用register时抛出NPE(UserService是一个类而不是接口/抽象btw)。我想知道是否有一些注释(javax或Spring)可能与JMockit或其他东西发生冲突(虽然我已尝试删除它们)?

我尝试将注射剂切换到@Mocked,我尝试将其删除并将其作为@Mocked测试方法参数。似乎没有什么能解决NPE。

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,问题在于混合Spring注释 - 与Java Resource自动连接。如果你混合它们只会注入Java。 有关详细信息,请查看: mockit.internal.expectations.injection.InjectionPoint
mockit.internal.expectations.injection.FieldInjection
特别是discardFieldsNotAnnotatedWithJavaxInjectIfAtLeastOneIsAnnotated方法。

这是解决问题的肮脏方法:

package mockit.internal.expectations.injection;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;


public class DirtyHack {

    static {
        try {
            setFinalStatic(InjectionPoint.class.getDeclaredField("WITH_INJECTION_API_IN_CLASSPATH"), false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

        field.set(null, newValue);
    }
}

然后你的测试需要扩展这个类。

答案 1 :(得分:0)

我最终使用反射手动设置@Tested类

中的@Injectable字段
public class UserResourceTest {
    @Tested UserResource userResource;
    @Injectable UserService userService;
    @Mocked BaseResource baseResource;

    @Test
    public void registerShouldDoSomething(){
        Deencapsulation.setField(userResource,userService); //This line
        User user = new User();
        final User registerResult = new User();
        ...
        new NonStrictExpectations() {{
            userService.register((User)any); result = registerResult;
        }};
        userResource.registerUser(user);
        ...
    }
}

仍然不确定该错误是什么,但这对我有用