Is creating "internal" methods for removing dependencies (for unit tests) a good practice? Any better way?

I have a class as follows.

public class MyClass  
{  
    public MyMethod()  
    {  
      int x = CalculateSomething();  
    }

   private int CalculateSomething()  
   {  
      // Do something and return an int    
      return 100;  
   }  
}  

In the unit test, I added this [assembly: InternalsVisibleTo("MyTests")]and changed the private method as an internal virtual one. In the unit test project, I created a class MockMyClassand created a private method as follows.

public class MockMyClass : MyClass  
{  
   public bool MadeHappyNoise {get; set;}
   internal override int CalculateSomething()  
   {  
      MadeHappyNoise = true;  
      return base.CalculateSomething();  
   }  
}

unit test is as follows

[TestMethod()]
public void WasCalculateSomethingCalledOK()  
{  
   MockMyClass mk = new MockMyClass();
   mk.MyMethod();  
   Assert.IsTrue(mk.MadeHappyNoise, "Oops...CalculateSomething not called...");  
}  

A few questions: Is this a good way to remove dependencies? I personally do not like to change the method from private to internal, but have no option (other than using Reflection, maybe). Also, the InternalsVisibleTo ("MyTests") attribute residing in production code is not very good. Can someone point me to a better solution please? Thank.

+5
5

. , .

  • , MyMethod CalculateSomething? , , , (, CalculateSomething2, , ?). MyMethod, , unit test.

  • , MyMethod , . , unit test , MyMethod ?

    , MyMethod , ( , --, , . " , ).

  • MyMethod, , , (, "" ).

    (, RhinoMocks), . , .

    mocks , .

+1

, :

public class MyClass  
{  
    private Calculator calculator;  

    public myMethod()  
    {  
      int x = calculateSomething();  
    }

    public void SetCalculator( Calculator c ){
        calculator = c;  
    }

   private int calculateSomething()  
   {  
        return calculator.CalculateSomething();
   }  
}  

MyClass

public Class Calculator {

   public virtual int CalculateSomething()  
   {  
      // Do something and return an int    
      return 100;  
   }  
}

, , .

+1

, . A unit - - .

, . , , .

, , , , - . , , .

+1

. ( ) , MyMethod . unit test , MyMethod() - , / MyMethod?.

- , .

InternalsVisibleTo .. , , . MyMethod(). , , , .

+1

, , unit test, MyClass. MyClass, x.

The unit test just created claims that the value of x is 100 after creating MyClass. Once you have it, refactoring like @alb offers. Run the test again, make sure x is still 100 and check the calculator class separately and ultimately remove the preliminary public property for x in MyClass. hope this helps.

0
source

All Articles