目前,我正在使用内存中的数据库测试一个实体框架的 DbContext。
为了使测试尽可能具有原子性,DbContext在每个测试方法中都是唯一的,并且使用每个测试所需的初始数据填充。
为了设置DbContext的初始状态,我创建了一个void SetupData方法,它用我将在测试中使用的一些实体填充上下文。
这种方法的问题是,在安装过程中创建的对象不能被测试访问,因为实体框架将分配Ids本身,直到运行时为止都是未知的。
为了克服这个问题,我认为我的SetupData方法可以变成这样:
public Fixture SetupData(MyContext context)
{
var fixture = new Fixture();
fixture.CreatedUser = new User();
context.Users.Add(fixture.CreatedUser);
context.SaveChanges();
return fixture;
}
public class Fixture
{
public User CreatedUser { get; set;}
}正如您所看到的,它正在返回我所称的“治具”的实例。(我不知道这个名字是否合身)。
这样,SetupData将返回带有对实体的引用的对象(Fixture) 。因此,测试可以使用创建的对象。否则,对象将无法识别,因为在调用SaveChanges之前不会创建Id。
我的问题是:
发布于 2018-04-20 14:24:13
这是一个不错的做法。事实上,这是一种很好的方法,可以创建可读的给定的测试。如果你考虑:
SetupData方法public static MyContextExtensions
{
public static User Given(this MyContext @this, User user)
{
@this.Users.Add(user);
@this.SaveChanges();
return user;
}
public static OtherEntity Given(this MyContext @this, OtherEntity otherEntity)
{
// ...
}
// ...
}然后您可以编写(一个概念示例,需要修改细节以匹配您的实现):
[Test]
public GivenAUser_WhenSearchingById_ReturnsTheUser()
{
var expectedUsername = "username";
var user = _context.Given(AUser.WithName(expectedUsername));
var result = _repository.GetUser(user.Id);
Assert.That(result.Name, Is.EqualTo(expectedUsername));
}..。其他实体也是如此。
发布于 2018-04-19 17:05:15
我更喜欢这种方法:
public void SetupData(MyContext context)
{
var user = new User() { Id = Fixture.TEST_USER1_ID, UserName = Fixture.TEST_USER1_NAME };
context.Users.Add(user);
context.SaveChanges();
}
public class Fixture
{
public const int TEST_USER1_ID = 123;
public const string TEST_USER!_NAME = "testuser";
}您的方法可能也很好,但是您可能希望知道测试中的某个位置的用户ID,这使得在一个已知位置指定它非常容易,这样如果您稍后更改测试数据和添加用户的顺序,它就不会改变。
https://stackoverflow.com/questions/49925892
复制相似问题