unit tutorial test mockbean baeldung java spring unit-testing dependency-injection mockito

java - tutorial - Inyectando una propiedad String con @InjectMocks



spring test (2)

No puedes hacer esto con Mockito, pero Apache Commons en realidad tiene una manera de hacerlo usando una de sus utilidades integradas. Puedes poner esto en una función en JUnit que se ejecuta después de que Mockito inyecte el resto de los simulacros pero antes de que se ejecuten los casos de prueba, como esto:

@InjectMocks MyClass myClass; @Before public void before() throws Exception { FieldUtils.writeField(myClass, "fieldName", fieldValue, true); }

Tengo un Spring MVC @Controller con este constructor:

@Autowired public AbcController(XyzService xyzService, @Value("${my.property}") String myProperty) {/*...*/}

Quiero escribir una prueba de unidad independiente para este controlador:

@RunWith(MockitoJUnitRunner.class) public class AbcControllerTest { @Mock private XyzService mockXyzService; private String myProperty = "my property value"; @InjectMocks private AbcController controllerUnderTest; /* tests */ }

¿Hay alguna forma de que @InjectMocks inyecte mi propiedad String? Sé que no puedo burlarme de una Cuerda ya que es inmutable, pero ¿puedo inyectar una Cuerda normal aquí?

@InjectMocks inyecta un nulo por defecto en este caso. @Mock comprensiblemente lanza una excepción si la pongo en myProperty . ¿Hay alguna otra anotación que haya omitido que simplemente signifique "inyectar este objeto exacto en lugar de una burla"?


No puedes hacer esto con Mockito, porque, como mencionaste, una String es final y no puede ser burlada.

Hay una anotación de @Spy que funciona en objetos reales , pero tiene las mismas limitaciones que @Mock , por lo que no puede espiar una String .

No hay anotación para decirle a Mockito que solo inyecte ese valor sin burlarse o espiar. Sin embargo, sería una buena característica. Tal vez lo sugiera en el repositorio de Mockito Github .

Tendrá que crear una instancia manual de su controlador si no desea cambiar su código.

La única forma de tener una prueba basada en anotación pura es refactorizar el controlador. Puede usar un objeto personalizado que solo contiene esa propiedad, o tal vez una clase de configuración con múltiples propiedades.

@Component public class MyProperty { @Value("${my.property}") private String myProperty; ... }

Esto se puede inyectar en el controlador.

@Autowired public AbcController(XyzService xyzService, MyProperty myProperty) { ... }

Puedes burlarte e inyectar esto entonces.

@RunWith(MockitoJUnitRunner.class) public class AbcControllerTest { @Mock private XyzService mockXyzService; @Mock private MyProperty myProperty; @InjectMocks private AbcController controllerUnderTest; @Before public void setUp(){ when(myProperty.get()).thenReturn("my property value"); } /* tests */ }

Esto no es muy sencillo, pero al menos podrá realizar una prueba basada en anotaciones puras con un poco de stubbing.