C# 跳过单元测试中的内部方法调用
比如说,我有方法A,B,C和DC# 跳过单元测试中的内部方法调用,c#,unit-testing,xunit,C#,Unit Testing,Xunit,比如说,我有方法A,B,C和D public bool A (int foo) { bool result = false; if (foo > 0) result = B(); else result = C(); D(foo); return result; } 我想为a编写一个单元测试,调用B或C,但想跳过D调用(因为这是一个使用外部服务的方法)。是否可以使用某些属性跳过D调用?或者模拟D,用一些假服务替换它?这突出了设计代码
public bool A (int foo)
{
bool result = false;
if (foo > 0)
result = B();
else result = C();
D(foo);
return result;
}
我想为a编写一个单元测试,调用B或C,但想跳过D调用(因为这是一个使用外部服务的方法)。是否可以使用某些属性跳过D调用?或者模拟D,用一些假服务替换它?这突出了设计代码以使其可进行单元测试的重要性。依赖注入在这方面非常有用。然后,您可以在单元测试时模拟依赖项。例如,您可以通过接口ICommunications访问通信层。然后,类将引用其构造函数中的ICommunications对象:
public class TestableClass
{
private ICommunications _comms;
public TestableClass(ICommunications comms)
{
_comms = comms;
}
public bool FunctionToTest()
{
//do something testable
_comms.SomeFunction();//mocked object in unit tests
//do something else testable
}
}
然后只需创建一个模拟版本的comms,并在测试过程中传递它。您还可以向模拟类添加代码,以模拟某些测试条件,例如,对于接收一些无效数据的通信层。您需要使具有方法
a()
的类依赖于方法D()
使用的外部服务。您可以使用任何DI模式来实现这一点,尽管构造函数注入可能是最好的起点
在这种情况下,可以伪造所依赖的外部服务D()
,并将其注入类中。测试现在由您通过假冒者的行为进行控制
比如:
class Thing
{
private IExternalService _externalService;
public Thing(IExternalService externalService)
{
_externalService = externalService;
}
public void A() { ... }
public void D(string foo)
{
_externalService.DoSomeStuff();
}
}
然后:
您需要模拟方法D。我使用Typemock Isolator编写了一个示例,请看:
class Methods
{
public bool A(int foo)
{
bool result = false;
if (foo > 0)
result = B();
else
result = C();
D(foo);
return result;
}
public void D(int foo) {throw new NotImplementedException();}
public bool C() { return false;}
public bool B() { return true;}
}
以及测试:
[TestMethod, Isolated]
public void TestIgnoreD()
{
//Arrange
Methods methods = new Methods();
Isolate.WhenCalled(() => methods.D(0)).IgnoreCall();
//Act
bool result = methods.A(1);
//Assert
Assert.IsTrue(result);
}
我把它们都放在一个类中,只是因为我不知道你的代码中发生了什么。无论如何,隔离器相当灵活,因为它允许模拟几乎所有地方的一切 您必须模拟
D
:如果输入A
method,您无法避免调用D
。是的,您必须模拟D。在任何一种情况下,您想要跳过D
调用本身就是问题所在。您不想修改您的单元,否则它不是真正的测试。您的测试应该将代码单元视为一个黑匣子。“我给它这个输入,我期望这个输出。”是的,但是每次我运行单元测试时,在外部系统中下一个命令似乎不是一个好主意。
[TestMethod, Isolated]
public void TestIgnoreD()
{
//Arrange
Methods methods = new Methods();
Isolate.WhenCalled(() => methods.D(0)).IgnoreCall();
//Act
bool result = methods.A(1);
//Assert
Assert.IsTrue(result);
}