简体   繁体   中英

Control doesn't go to the virtual method while debugging

I have a class with few methods. For these methods, I'm creating Unit Test cases using MSTest.

public class Class1
{
    public virtual async Task<bool> GetData()
    {
        string var1 ="dsfs", var2 ="eer";
        bool retVal = await DoSomething(var1, var2);
        // some business logic
        return true;
    }
    public virtual async Task<bool> DoSomething(string var1, string var2)
    {
        return true;
    }
}

The test cases for method GetData() looks like this.

[TestClass()]
public class Class1Test
{
    [TestMethod()]
    public async Task GetDataTest()
    {
        var mockService = new Mock<Class1>();
        var isTrue = ReturnTrue(); // this function returns true
        mockService.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>())).Returns(isTrue);
        var result = await mockService.Object.GetData();
        Assert.IsTrue(result);
    }
}

Now, the problem I'm facing is,

var result = await mockService.Object.GetData();

From this line the control doesn't go to the actual GetData() method in Class1 . If I remove virtual keyword from the method definition, then the control goes to the method, ie, if I make the method like this.

public async Task<bool> GetData()
{
    bool retVal = await DoSomething(var1, var2);
    // some business logic
    return true;
}

I need to make this method virtual because, this method is called in some other method say " XYZMethod " and for writing test case "XYZMethod", I had mocked GetData() method there.

So is there anyway I can solve this problem without removing virtual keyword.

PS: Writing interfaces is not an option as this is a very heavy code which I'm working on and introducing Interface at this stage is not practical.

Enable CallBase on the mock so that it will invoke base members that have not been overridden by a setup expectation.

Also use ReturnsAsync when configuring asynchronous mocked members to allow them to flow correctly when invoked.

[TestClass()]
public class Class1Test {
    [TestMethod()]
    public async Task GetDataTest() {
        //Arrange
        var mockService = new Mock<Class1>(){
            CallBase = true
        };
        var expected = ReturnTrue(); // this function returns true
        mockService
            .Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
            .ReturnsAsync(expected);

        //Act
        var actual = await mockService.Object.GetData();

        //Assert
        Assert.IsTrue(actual);
    }
}

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