我是单元测试的新手。任何人都可以向我解释如何在不打击数据库的情况下完成单元测试。
我还想知道,依赖注入是否对单元测试至关重要? 如果是,请用示例代码向我解释。这对我有帮助。
我已经创建了用于登录的单元测试,它可以访问数据库。但我想为登录测试相同的情况,而不是打击数据库。 在这里,我使用 Microsoft.VisualStudio.TestTools.UnitTesting 。
这是我的代码,
[TestMethod]
public void _01_LoginUser_01_Valid()
{
BLUser.User.UserDTO user = new BLUser.User.UserDTO();
user.UserName = "mohan";
user.UserPassword = "abc";
BLUser.Model.Fs_User result = BLUser.User.LoginUser(user);
Assert.AreEqual("mohan", result.UserName);
}
我的业务逻辑是,
public static Fs_User LoginUser(UserDTO userDTO)
{
try
{
var context = new UserDBEntities();
{
var LoginUser = context.Fs_User.Where(u => u.UserName == userDTO.UserName && u.UserPassword == userDTO.UserPassword).SingleOrDefault();
if (LoginUser == null)
ValidationError.LoginException((int)ExceptionCodes.InvalidPassword);
return LoginUser;
}
}
catch (Exception ex)
{
throw ex;
}
}
答案 0 :(得分:3)
请在此处查看我的回答:Solid Principle examples anywhere?
如果你想看一下依赖于数据访问界面的想法,你就会看到如何提供一个虚假的'用于测试的接口的实现,不依赖于数据库。
根据您的示例,您需要进行以下更改:
public class LoginThing
{
private readonly IAmSomeContext context;
public LoginThing(IAmSomeContext context)
{
this.context = context;
}
public Fs_User LoginUser(UserDTO userDTO)
{
try
{
var LoginUser =
this.context.Fs_User
.SingleOrDefault(
u =>
u.UserName == userDTO.UserName
&& u.UserPassword == userDTO.UserPassword);
if (LoginUser == null)
ValidationError.LoginException((int)ExceptionCodes.InvalidPassword);
return LoginUser;
}
catch (Exception ex)
{
throw ex;
}
}
}
然后你的测试就会变成:
[TestMethod]
public void _01_LoginUser_01_Valid()
{
BLUser.User.UserDTO user = new BLUser.User.UserDTO();
user.UserName = "mohan";
user.UserPassword = "abc";
var fakeContext = CreateFakeContextWith(user);
var thingUnderTest = new LoginThing(fakeContext);
BLUser.Model.Fs_User result = thingUnderTest.LoginUser(user);
Assert.AreEqual("mohan", result.UserName);
}
如果使用NSubstitute:
,创建虚假上下文就像这样private IAmSomeContext CreateFakeContextWith(BLUser.User.UserDTO user)
{
var fakeContext = Substitute.For<IFakeContext>();
fakeContext.Fs_User.Returns(new List(new[] {user}));
return fakeContext;
}
语法可能不完全正确,但你明白了......