编写单元测试时省略方法中的一些方法,以及测试方法的一些条件

时间:2016-09-20 01:24:11

标签: c# unit-testing mocking nunit rhino-mocks

如何在正在测试的大方法中编写逃避或绕过一些方法和条件的测试。

例如,我有以下方法:

public bool IsValid(int id)
{

 var details = _myService.GetDetails(id); // This line should be avoided in test
 var doctorDetails = _myService.GetDoctorDetails("AUS"); // This needs to be executed

if(details.Name == "Ab") // This if I dont want to be part of my test
{
 // Do something

}

if(doctorDetails !=null )
{
// Code to test

}

}

编辑我的代码,我只需要在我的方法中测试第二个IF语句。我需要对doctorDetails的值进行编码,以便从服务中获取数据,如上所示,因为,为了从服务中获取数据,应该有详细信息,但事实并非如此。否则,只有选项是模拟它并在DB中存储细节并调用此服务,我现在不想这样做

1 个答案:

答案 0 :(得分:1)

概念是我们需要能够存根其他服务,以便我们可以执行第二个IF语句。请注意,我们不想与真实服务交谈,因为它违背了单元测试的目的。对不起,我不确定你打算单元测试的确切行为,但希望下面会指出你正确的方向。

public class PatiantDetail {
    public string Name { get; set; }
}

public class DoctorDetail {
    public string Name { get; set; }
}

public interface IService {
    PatiantDetail GetPatiantDetail(int id);
    DoctorDetail GetDoctorDetail(string countryCode);
}

//System Under Test
public class Sut
{
    private readonly IService _myService;

    public Sut(IService service)
    {
        _myService = service;
    }

    public bool IsValid(int id)
    {
        var details = _myService.GetPatiantDetail(id); // This line should be avoided in test
        var doctorDetails = _myService.GetDoctorDetail("AUS"); // This needs to be executed

        if (details.Name == "Ab") // This if I don't want to be part of my test
        { // Do something 
        }

        if (doctorDetails != null)
        {// Code to test
        }

        return true;
    }
}


[TestClass]
public class UnitTestClass
{
    [TestMethod]
    public void TestMethodForDemostationOfStubbing()
    {
        //Qustion: "How to write tests that escapes or bypasses few methods and conditions inside a big method that is being tested"
        //Answer:
        //This is pivotal to Unit Testing as we should be able to isolate dependencies and test what is only reequired. 
        //As soon as we concern about calling real services/db, it becomes an Integration Test :)
        //There are many ways to do isolate dependencies in your test. For example, 
        //  a. Poor man's techniques. (too much code you may have to write)
        //  b. Using an isolation framework. i.e Rhyno Mock you already using. (less code you have to write)


        //Using your example
        //"I need only the second IF statement to be tested in my method."

        //Arrange
        int id = 3;
        var stubService = MockRepository.GenerateStub<IService>();
        stubService.Expect(x => x.GetPatiantDetail(Arg<int>.Is.Anything)).Return(new PatiantDetail() {Name = ""}); //so the first *if* statement get bypass. i.e not to return "Ab"

        //"I need to harcode the value of doctorDetails against to fetching its data from service as indicated above"
        stubService.Expect(x => x.GetDoctorDetail(Arg<string>.Is.Anything)).Return(new DoctorDetail()); //returns an object with any hard coded data so the second *if* statement get executed.


        var sut = new Sut(stubService);

        //Act
        var isValid = sut.IsValid(id);

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