我正在研究一个 CRUD 测试课程,因为我厌倦了在验证我的 NHibernate 映射时重复相同的测试模式。
我已经重构了代码,并且已经达到了一切都按照我设想的方式工作的地步,但我感到很恼火。一切都基于字符串,反射方法使用这些字符串调用适当的存储库方法并获取相应属性的值,如实体 ID。
这行得通,但我确信我不需要为这些事情使用字符串。
所以我开始使用 Linq。我不是一个重度 Linq 用户,下面的代码让我完全困惑。
它工作得几乎完美(我会在一秒钟内完成),我很高兴它工作得很好,但我真的很想知道为什么。
[Test]
public void TestCanUseTesterWithLinqSecondEffort()
{
IRepositoryTestContextManager contextManager = new NHRepositoryTestContextManager();
contextManager.SetUpRepositoryContextAndSchema();
TestInsertMethodWithLinq<NHClientRepository, Client>((x, y) => x.InsertClient(y), _newClient);
contextManager.ResetRepositoryContext();
Client retrievedClient = TestRetrieveMethodWithLinq<NHClientRepository, Client, string>((clientRepository, publicId) => clientRepository.GetClient(publicId), client => client.PublicId, _newClient);
contextManager.TearDownRepositoryContext();
Assert.IsNotNull(retrievedClient);
Assert.AreNotSame(_newClient, retrievedClient);
Assert.AreEqual(_newClient.Id, retrievedClient.Id);
Assert.AreEqual(_newClient.PublicId, retrievedClient.PublicId);
Assert.AreEqual(_newClient.Name, retrievedClient.Name);
}
private void TestInsertMethodWithLinq<TRepositoryType, TEntityType>(Action<TRepositoryType, TEntityType> insertMethod, TEntityType entity)
where TRepositoryType : class, new()
{
insertMethod.Invoke(new TRepositoryType(), entity);
}
private TEntityType TestRetrieveMethodWithLinq<TRepositoryType, TEntityType, TArgumentType>(Func<TRepositoryType, TArgumentType, TEntityType> retrieveMethod, Func<TEntityType, TArgumentType> paramValue, TEntityType theEntity)
where TRepositoryType : class, new()
{
return retrieveMethod.Invoke(new TRepositoryType(), paramValue(theEntity));
}
具体来说,我说的是两个调用的委托(我知道一个不必调用调用来使用委托。我将其包括在内以进行澄清)。编译器如何转换 Linq 表达式,以便在新实例化的类(在本例中为 TRepositoryTypes)上调用正确的方法?
关于“几乎完美”中的几乎,如果在调用方法的处理过程中出现异常,则将异常吞噬。也不知道为什么会这样,但我已经可以看到测试未完成并且由于异常被吞没而遗漏了问题的场景。
咀嚼那个。提前致谢。