Rus*_*ino 2 c# unit-testing moq
我有以下测试.
[TestFixture]
public class AdministratorRepositoryTests
{
private IAdministrateurRepository repository;
public static IAdministrateurRepository MockAdministrateurRepository(params Administrateur[] items)
{
var mockRepos = new Mock<IAdministrateurRepository>();
mockRepos.Setup(x => x.Select()).Returns(items.AsQueryable());
return (IAdministrateurRepository)mockRepos.Object;
}
[SetUp]
public void SetupContext()
{
Guid gId1 = new Guid("a05fd3de-9ae4-4b0b-b560-fd96678d3019");
Administrateur a1 = new Administrateur(gId1);
Guid gId2 = new Guid("e0724d12-d856-4677-89aa-d12611c15a4c");
Administrateur a2 = new Administrateur(gId2);
Guid gId3 = new Guid("30a69d49-84e5-42fc-a643-9e42c1350aa8");
Administrateur a3 = new Administrateur(gId3);
Guid gId4 = new Guid("b6444711-baee-4da6-87a8-a839c438bdff");
Administrateur a4 = new Administrateur(gId4);
Guid gId5 = new Guid("9d805acd-9d59-44ac-892c-438b189bbf94");
Administrateur a5 = new Administrateur(gId5);
repository = MockAdministrateurRepository(a1, a2, a3, a4, a5);
}
[Test]
public void peut_recuperer_un_administrateur_dun_repository_par_son_id()
{
Guid monGuid = new Guid("a05fd3de-9ae4-4b0b-b560-fd96678d3019");
var administrateur = repository.SelectById(monGuid);
administrateur.ShouldNotBeNull();
administrateur.Id.ShouldEqual(monGuid);
}
}
Run Code Online (Sandbox Code Playgroud)
我很难理解为什么管理员返回NULL.
var administrateur = repository.SelectById(monGuid);
Run Code Online (Sandbox Code Playgroud)
我甚至对存储库进行了计数测试,它有5个项目.
有帮助吗?
我经常看到这个问题 - 你从根本上误解了嘲讽/伪造/抄袭的目的是什么.也就是说,你正在编写一个虚假实现的测试,因此,测试是没用的.想一想 - 你的测试试图证明什么?您正在尝试验证是否可以从存储库中获取结果,但是:
// this is a mock/fake/stub/whatever, it's NOT the real class
var repository = new Mock<IAdministrateurRepository>();
// and so.. what is the point in this when your
// IAministratorRepository is not the production version?
var administrateur = repository.SelectById(monGuid);
// The repository is meant to be the focus of the test,
// yet you're not testing a result of using a real class
administrateur.ShouldNotBeNull();
administrateur.Id.ShouldEqual(monGuid);
Run Code Online (Sandbox Code Playgroud)
上面的行是从您的存储库中提取数据,但存储库不是真正的实现.这不是生产代码.如果是这样,那么为什么然后断言Administrator从假存储库中取出的对象呢?您正在测试的行为是ID功能搜索,但它是在您的测试夹具中定义的!您已经创建了一个存根/伪实现,然后对其进行了测试 - 仅此而已.Mocks/Stubs/Fakes意味着有预期或提供预制结果来推动真实类型的测试(阅读:生产中使用的类型).测试模拟本身没有任何结果.
在编写任何测试代码之前,您应该问自己这个测试的目的是什么? 如果您无法回答该问题,请在编写测试代码之前解决该问题.如果你真的要测试你的AdministratorRepository,你将实例化存储库的生产代码版本然后操纵它,然后在其行为的某些方面断言.
这篇博文可能对您有所帮助.我主张放弃模拟框架并使用基于状态的测试,直到你完全清楚模拟/存根适合的位置,因为它很容易被基于交互的测试弄糊涂.
*编辑 - 好的,这里(粗略地)你的代码看起来应该是什么 忽略实现细节,只关注每种类型的角色,并注意到它很简单.
// interface
public interface IAdministratorRepository
{
Administrator SelectById(Guid _id);
void Add(Administrator _admin);
}
// minimal implementation of admin.
public class Administrator
{
public Guid Id { get; set; }
public Administrator(Guid _id)
{
Id = _id;
}
}
/// <summary>
/// For argument's sakes, this is the class under test.
/// It's not a mock/fake/stub/whatever; it's the real deal!
/// </summary>
public class RealAdministratorRepository : IAdministratorRepository
{
private Dictionary<Guid, Administrator> m_items = new Dictionary<Guid, Administrator>();
public Administrator SelectById(Guid _id)
{
// no error handling here; keeping it simple
if(m_items.ContainsKey(_id))
return m_items[_id];
return null;
}
public void Add(Administrator _admin)
{
// No error handling for brevity's sakes
m_items.Add(_admin.Id, _admin);
}
}
// now, here's a very, very simple happy path test for SelectById using
// the real implementation of AdministratorRepository
[TestFixture]
public class AdministratorRepositoryTests
{
private const string AdminId = "a05fd3de-9ae4-4b0b-b560-fd96678d3019";
private IAdministratorRepository m_repository;
[SetUp]
public void PerTestSetUp()
{
// no mocks/stubs required. m_repository is a RealAdministratorRepository
// because that's our production class and that's what we want to test!
m_repository = new RealAdministratorRepository();
m_repository.Add(new Administrator(new Guid(AdminId)));
}
[Test]
public void SelectById_WithItemsInRepository_ReturnsCorrectItems()
{
// ignore the fact that I'm repeating the same string 3 times; brevity again
var item = m_repository.SelectById(new Guid(AdminId));
Assert.That(item, Is.Not.Null);
Assert.That(item.Id, Is.EqualTo(new Guid(AdminId)));
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我没有使用模拟框架,因为我不需要.生产代码没有任何需要模拟/存根/伪造的有问题的依赖项.