如何在正在测试的大方法中编写逃避或绕过一些方法和条件的测试。
例如,我有以下方法:
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中存储细节并调用此服务,我现在不想这样做
答案 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);
}
}