如果您想以适当隔离的方式(即单元测试)测试 GetName 方法,那么您不能使用 new 在方法本身中创建 UserRights 实例;因为测试实际上只是代码的另一个客户端,因此它不能(也不应该)知道GetName 在内部是如何工作的
所以这意味着对于正确的单元测试,您必须能够将方法的所有依赖项替换为客户端完全控制的依赖项 - 在这种情况下,单元测试中的代码是客户。
在您发布的代码中,客户端代码完全无法控制 UserRights 或 DatabaseContext,因此这是必须更改的第一件事。
您需要重新编写代码,以便客户端可以提供UserRights 实现。事实上,一旦完成,DatabaseContext 来自哪里的问题实际上与单元测试无关,因为它不关心UserRights 本身如何执行其任务!
有很多方法可以做到这一点;你可以使用 Mocks 或 Stubs,你可以使用构造函数或方法注入,你可以使用 UserRights 工厂。这是一个使用非常简单的存根的示例,恕我直言,这是最好的开始方式,并且避免了学习 Mocking 框架——我个人会为此使用 Mocks,但那是因为我很懒 :)
(下面的代码假设包含 GetName 的类称为“UserService”,并使用 xUnit 框架;但 MSTest 也可以正常工作)
假设您可以控制UserService 的代码,因此您可以将LookupNameByID 方法设为虚拟(如果您不能,那么您可能必须使用接口和模拟的路径)
public class UserRights
{
public virtual LookupNameByID(string id)
{
//does whatever a UserRights does.
}
}
public class UserService
{
readonly UserRights _rights;
public UserService(UserRights rights)
{
_rights=rights; //null guard omitted for brevity
}
public string GetName(string id)
{
return _rights.LookupNameByID(id);
}
}
现在在您的单元测试代码中假设您像这样创建UserRights 的子类:
public class ExplodingUserRights: UserRights
{
public override string LookupNameByID(string id)
{
throw new Exception("BOOM!");
}
}
现在您可以编写一个测试来查看GetName 在发生不良情况时的反应:
[Fact]
public void LookupNameByID_WhenUserRightsThrowsException_DoesNotReThrow()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new ExplodingUserRights()); <-Look, no DatabaseContext!
sut.GetName("12345");
}
当好事发生时:
public class HappyUserRights: UserRights
{
public override string LookupNameByID(string id)
{
return "yay!";
}
}
[Fact]
public void LookupNameByID_ReturnsResultOfUserRightsCall()
{
//this test will fail if an exception is thrown, thus proving that GetName doesn't handle exceptions correctly.
var sut = new UserService(new HappyUserRights());
var actual = sut.GetName("12345");
Assert.Equal("yay!",actual);
}
等等。请注意,我们从来没有接近过DatabaseContext,因为这是一个你只需要在对UserRights 类本身进行单元测试时解决的问题。(那时我可能会建议使用 Jeroen 的建议)从他的链接文章中,并进行集成测试,除非您不能或不会为每个测试设置数据库,在这种情况下您需要使用接口和模拟)
希望对您有所帮助。