简体   繁体   中英

How to mock a normal method inside a static class in C#?

I need to mock a normal method inside a static method

My method is something like this and is it possible to mock TestResult here?

I have done with mocking a method inside a method by using an interface, but here static methods that

public static ClassData()
{

       public static string GetData()
       {
           //Wish to mock TestResult method
           TestData TD=new TestData();
           string FinalResult=TD.TestResult();
           //Some logic
           Return FinalResult;   
      }


}

The answer is "No, there is no way to mock without changing an existing code".

The fact that code cannot be covered with a unit test easily is a proof indicator that something is wrong with the code itself. So I'd really recommend to revisit the approach.

If this is not a practical task, you can try the following trick. Expose TestData as a property with public setter (which you'd set in the test code):

public static class ClassData
{

    public static string GetData()
    {
        //Wish to mock TestResult method
        TestData TD = new TestData();
        string FinalResult = TestData.TestResult();
        //Some logic
        return FinalResult;
    }

    public static TestData TestData { private get; set; }
}

public class TestData
{
    public virtual string TestResult()
    {
        return string.Empty;
    }
}

Just an idea of a test body:

var testDataMock = new Mock<TestData>(); // Moq as example
testDataMock.Setup(t => t.TestResult()).Returns("some string");
ClassData.TestData = testDataMock.Object; 
var result = ClassData.GetData();

//Assertions

Split the current function into two parts:

public static ClassData()
{
   public static string GetData()
   {
       //Wish to mock TestResult method
       TestData TD=new TestData();
       string FinalResult=TD.TestResult();
       return GetData2(FinalResult);   
  }
  public static string GetData2(string FinalResult)
  {
       //Some logic
       return FinalResult;   
  }       
}

In your test case, call GetData2 instead of GetData , and now you can test "some logic" with appropriate input values.

Note that GetData2 could be internal when you use the InternalsVisibleTo attribute.

Using Isolator you can simply do:

public static class ClassData
    {
        public static string GetData()
        {
            //Wish to mock TestResult method
            TestData td = new TestData();
            string finalResult = td.TestResult();
            //Some logic
            return finalResult;
        }

    }

    [TestMethod, Isolated]
    public void Test_MockFinalResult()
    {
        var fakeTestData = Isolate.Fake.NextInstance<TestData>();
        Isolate.WhenCalled(() => fakeTestData.TestResult()).WillReturn("test");
        var str = ClassData.GetData();
        Assert.AreEqual("test",str);
    }

Or did you have something else in mind?

There is no need to make the class static. You can have a static method inside a non static class. You can then have the static method call a non static method.

   public class test
    {

        public static string GetData()
        {
            //Wish to mock TestResult method
            TestData TD = new TestData();
            string FinalResult = TD.TestResult();
            //Some logic
            return FinalResult;
        }
        public class TestData
        {
            public string TestResult()
            {
                return "Hello World";
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM