我在Asp.Net Web API中有3层。使用EF实现控制器层,服务层和存储库层。
我是单元测试的新手,并且拥有一个简单的函数,可以通过数据库中的id获取一个人,而不是别的。
服务层基本上调用
Unit_Work.Person_Repository.GetPersonByID(id);
并且存储库执行此操作:
return context.chapters.Where(p=>p.chapterID==id).SingleOrDefault();
提前感谢所有回答的人。
答案 0 :(得分:0)
如果您使用的是实体框架,则无法对数据访问层进行单元测试。
Erik Alsmyr提供的解决方案非常错误! 看看为什么 - What's the point of in memory IDbSet?。
在内存数据库集中使用时,您正在运行Linq to Objects。当您使用EF的DbContext时,您的Linq将转换为SQL。这是两件不同的事情!
编写将在内存数据库集中工作的代码非常容易(所有单元测试都将通过,您会很高兴)只是为了在第一次尝试命中数据库时发现运行时错误。
让我们稍微修改一下这段代码。如果我们使用FIRSTNAME,LASTNAME,我认为FULLNAME不应该有setter。它应该从FIRSTNAME和LASTNAME计算。
class User
{
public string FIRSTNAME { get; set; }
public string LASTNAME { get; set; }
public string FULLNAME
{
get { return string.Format("{0}, {1}", LASTNAME, FIRSTNAME }
}
User(string firstName, string lastName)
{
this.FIRSTNAME = firstName;
this.LASTNAME = lastName;
}
}
现在你可以像这样编写测试并且它会通过(当然你在控制器中实现它之后)
public IMyEntities GetRepoWithUsers(params User[] users)
{
var inMemoryUsers = new InMemoryDbSet<User>();
var mockData = new Mock<IMyEntities>();
mockData.Setup(m => m.Users).Returns(inMemoryUsers);
return mockData.Object;
}
[Test]
public void GetUserByFullname()
{
var ankaArne = new User("Arne", "Anka");
var bjornBertil = new User("Bertil", "Björn");
var repo = GetRepoWithUsers(ankaArne, bjornBertil);
var usersController = new UsersController(repo);
var found = usersController.GetUser("Anka, Arne");
Assert.NotNull(found);
Assert.AreEqual("Anka", found.LASTNAME);
Assert.AreEqual("Arne", found.FIRSTNAME);
}
但是当你针对'真正的'DbContext和'真正的'DbSet运行它时它会抛出,因为你无法对计算出的属性进行Linq查询。仅限映射到数据库列的那些。那么这个测试有什么意义呢?
答案 1 :(得分:-1)
您可以将xml / .csv文件用于数据。即,您需要从单元测试项目中的xml文件中获取ID,章节详细信息。然后,您必须将id作为参数传递,然后使用xml文件中的数据提取检查返回值。如果你不明白让我知道。您可以通过添加新项目选项来创建单元测试项目。然后在vs2010上选择添加xml文件以获取要测试的数据。
你的第3个问题也是正确的。 u cn从数据库填充数据并使用返回值检查数据
答案 2 :(得分:-1)
我建议在您的存储库中模拟并注入Entity框架上下文。
我们使用与http://nuget.org/packages/FakeDbSet/
类似的内容来执行此操作然后我们的单元测试看起来像这样:
[TestFixture]
class UsersControllerTester
{
private Mock<IMyEntities> mockData = null;
[SetUp]
public void Setup()
{
// Create fake data
var inMemoryUsers = new InMemoryDbSet<User>();
inMemoryUsers.Add(new User { ID = 1, FIRSTNAME = "Arne", LASTNAME = "Anka", EMAIL = "arne.anka@email.com", FULLNAME = "Anka, Arne", USERNAME = "arne.anka" });
inMemoryUsers.Add(new User { ID = 2, FIRSTNAME = "Bertil", LASTNAME = "Björn", EMAIL = "bertil.bjorn@email.com", FULLNAME = "Björn, Bertil", USERNAME = "bertil.bjorn" });
inMemoryUsers.Add(new User { ID = 3, FIRSTNAME = "Carl", LASTNAME = "Cool", EMAIL = "carl.cool@email.com", FULLNAME = "Cool, Carl", USERNAME = "carl.cool" });
inMemoryUsers.Add(new User { ID = 4, FIRSTNAME = "David", LASTNAME = "Dûsk", EMAIL = "david.dusk@email.com", FULLNAME = "Dûsk, David", USERNAME = "david.dusk" });
// Create mock unit of work
mockData = new Mock<IMyEntities>();
mockData.Setup(m => m.Users).Returns(inMemoryUsers);
}
[Test]
public void GetUser()
{
// Test
var usersController = new UsersController(mockData.Object);
// Invoke
User user1 = usersController.GetUser("1");
// Assert
Assert.NotNull(user1);
Assert.AreEqual(1, user1.ID);
Assert.AreEqual("Anka", user1.LASTNAME);
}