2014-10-31 61 views
1

我有一个类(看起来像这样)我试图测试。为什么在@Injectable类中有NPE

@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为空和投掷NPE当寄存器上调用它(UserService是一类不接口/抽象顺便说一句)。我想知道是否有些注释(javax或Spring)可能与JMockit或其他东西冲突(尽管我试过删除它们)?

我试着将注射剂切换到只是@Mocked,我试着将它移除并让它成为@Mocked测试方法参数。似乎没有什么能解决NPE。

+0

适用于我,没有NPE。它使用JUnit还是TestNG?哪个版本? JDK/JRE的版本是什么?什么版本的JMockit? – 2014-11-02 17:11:52

+0

JUnit 4.11 java 1.7,JMockit 1.13。你能想到任何理由一个模拟或注射将是空的?奇怪的是,Mocked BaseResource正在工作并且可以被嘲弄,但是那个UserService并不喜欢被嘲笑。 – 2014-11-03 17:25:01

+0

我无法重现这些版本的问题;不幸的是,不知道如何发生。 – 2014-11-03 19:40:43

回答

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); 
     ... 
    } 
} 

仍不能确定到底是什么错误,但是这对我的作品

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); 
    } 
} 

然后你的测试需要,例如扩展此类。

相关问题