variable usar son qué métodos método metodos metodo los llamar estáticos estático estaticos cuando c# .net mocking interface static-methods

c# - usar - un método estático



Cómo burlarse con métodos estáticos? (7)

Es posible que esté tratando de probar en un punto de partida demasiado profundo. No es necesario crear una prueba para probar cada método individualmente; Los métodos privados y estáticos deben probarse llamando a los métodos públicos que luego llaman a los privados y estáticos.

Entonces digamos que tu código es así:

public object GetData() { object obj1 = GetDataFromWherever(); object obj2 = TransformData(obj1); return obj2; } private static object TransformData(object obj) { //Do whatever }

No necesita escribir una prueba contra el método TransformData (y no puede). En su lugar, escriba una prueba para el método GetData que prueba el trabajo realizado en TransformData.

Soy nuevo para simular objetos, pero entiendo que necesito que mis clases implementen interfaces para burlarse de ellos.

El problema que tengo es que en mi capa de acceso a datos, quiero tener métodos estáticos, pero no puedo poner un método estático en una interfaz.

¿Cuál es la mejor manera de evitar esto? ¿Debería usar métodos de instancia (lo cual parece incorrecto) o hay otra solución?


Sí, usas métodos de instancia. Los métodos estáticos básicamente dicen: "Hay una forma de lograr esta funcionalidad: no es polimórfica". La burla se basa en el polimorfismo.

Ahora, si sus métodos estáticos lógicamente no se preocupan por la implementación que está utilizando, podrían tomar las interfaces como parámetros, o tal vez funcionar sin interactuar con el estado en absoluto, pero de lo contrario debería usar instancias (y probablemente inyección de dependencia para conectar todo junto).


Una solución simple es permitir el cambio de la implementación de la clase estática a través de un setter:

class ClassWithStatics { private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl(); // Should only be invoked for testing purposes public static void overrideImplementation(IClassWithStaticsImpl implementation) { ClassWithStatics.implementation = implementation; } public static Foo someMethod() { return implementation.someMethod(); } }

Entonces, en la configuración de sus pruebas, llama a overrideImplementation con alguna interfaz simulada. El beneficio es que no necesita cambiar clientes de su clase estática. La desventaja es que probablemente tengas un pequeño código duplicado, porque tendrás que repetir los métodos de la clase estática y su implementación. Pero algunas veces los métodos estáticos pueden usar una interfaz más ligera que proporciona la funcionalidad básica.


Use métodos de instancia cuando sea posible.

Utilice Func [T, U] estático público (referencias de funciones estáticas que pueden sustituirse por funciones simuladas) donde los métodos de instancia no son posibles.


El problema que tienes es cuando estás usando un código de terceros y se llama desde uno de tus métodos. Lo que terminamos haciendo es envolviéndolo en un objeto, y llamándolo pasándolo con dep inj, y luego su prueba unitaria puede simular un método estático de un tercero, llamar al colocador con él.


Encontré un blog en google con algunos buenos ejemplos sobre cómo hacer esto:

  1. Refactorizar clase para ser una clase de instancia e implementar una interfaz.

    Ya has declarado que no quieres hacer esto.

  2. Utilice una clase de instancia de contenedor con delegados para miembros de clases estáticas

    Al hacer esto, puede simular una interfaz estática a través de delegados.

  3. Utilice una clase de instancia contenedora con miembros protegidos que llaman a la clase estática

    Esta es probablemente la forma más fácil de burlar / administrar sin refactorizar, ya que solo puede heredarse y extenderse.


Yo usaría un patrón de objeto de método. Tener una instancia estática de esto, y llamarlo en el método estático. Debería ser posible hacer una subclase para las pruebas, dependiendo de su marco de burla.

es decir, en tu clase con el método estático tienes:

private static final MethodObject methodObject = new MethodObject(); public static void doSomething(){ methodObject.doSomething(); }

y su objeto de método puede ser muy simple, fácil de probar:

public class MethodObject { public void doSomething() { // do your thang } }