我的测试是使用像这样的模拟数据设置的
var persons = new List<Core.Domain.Person>
{
new Core.Domain.Person { DisplayName = "Coordinator 1", Email="coordinator01@wur.nl", WurAccount = "coord001" },
new Core.Domain.Person { DisplayName = "Coordinator 2", Email="coordinator02@wur.nl", WurAccount = "coord002" }
};
this.mockUnitOfWork.Setup(x => x.Query<Core.Domain.Person>()).Returns(persons.AsQueryable);
在测试人员的代码中,这样检索
private Dictionary<string, Domain.Person> GetPersons(IEnumerable<string> wurAccounts)
{
var accounts = wurAccounts.ToList();
return this.session.Query<Domain.Person>()
.Where(x => accounts.Contains(x.WurAccount))
.ToDictionary(x => x.WurAccount);
}
当我运行测试时,我在这里得到一个NullReferenceException:
at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
at Remotion.Linq.QueryableBase`1.GetEnumerator()
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable`1 source, Func`2 keySelector)
at Wur.P2G.Core.Services.PersonSynchronizer.GetPersons(IEnumerable`1 wurAccounts) in C:\Projects\P2G\P2G\Sources\Wur.P2G.Core\Services\PersonSynchronizer.cs:line 112
修改
我能够把它归结为仍然导致NullReference异常的这段代码:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using NHibernate;
using NHibernate.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Wur.P2G.Core.Services.Tests
{
public interface IUnitOfWork : IDisposable
{
ISession Session { get; }
IQueryable<T> Query<T>();
void BeginTransaction();
void Commit();
void Rollback();
}
public class Person
{
public virtual string WurAccount { get; set; }
public virtual string DisplayName { get; set; }
public virtual string Email { get; set; }
public virtual bool HasValidEmail => true;
public override string ToString() => WurAccount;
}
[TestClass()]
public class PersonSynchronizerTests
{
private Mock<IUnitOfWork> mockUnitOfWork;
private Mock<ISession> mockSession;
[TestInitialize]
public void Initialize()
{
this.mockUnitOfWork = new Mock<IUnitOfWork>();
this.mockSession = new Mock<ISession>();
this.mockUnitOfWork.Setup(x => x.Session).Returns(this.mockSession.Object);
}
[TestMethod()]
public void GetPersonsTest()
{
var persons = new List<Person>
{
new Person { DisplayName = "Coordinator 1", Email="coordinator01@wur.nl", WurAccount = "coord001" },
new Person { DisplayName = "Coordinator 2", Email="coordinator02@wur.nl", WurAccount = "coord002" }
};
this.mockUnitOfWork.Setup(x => x.Query<Person>()).Returns(persons.AsQueryable);
var wurAccounts = new[] { "coord001", "coord002" };
var accounts = wurAccounts.ToList();
var personsRead = mockSession.Object.Query<Person>()
.Where(x => accounts.Contains(x.WurAccount))
.ToDictionary(x => x.WurAccount);
}
}
}
更多文字,因为愚蠢的编辑想要它。
答案 0 :(得分:1)
虽然错误消息显示该问题与NHibernate.Linq
有关,但到目前为止显示的所有代码都与NHibernate
无关,除非您没有显示正在使用它的内容。
到目前为止显示的代码应该按预期工作,如下面基于提供的原始示例的最小,完整和可验证的示例所示。
[TestClass]
public class PersonSynchronizerTest {
[TestMethod]
public void PersonSynchronizer_GetPerson_Should_Return_Two() {
//Arrange
var wurAccounts = new[] { "coord001", "coord002" };
var persons = new List<Person> {
new Person { DisplayName = "Coordinator 1", Email="coordinator01@wur.nl", WurAccount = wurAccounts[0] },
new Person { DisplayName = "Coordinator 2", Email="coordinator02@wur.nl", WurAccount = wurAccounts[1] }
};
var mockSession = new Mock<ISession>();
mockSession.Setup(_ => _.Query<Person>()).Returns(persons.AsQueryable); //<-- setup session
var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(_ => _.Query<Person>()).Returns(persons.AsQueryable);
mockUnitOfWork.Setup(_ => _.Session).Returns(mockSession.Object); //<-- UoW returns session
var subject = new PersonSynchronizer(mockUnitOfWork.Object);
//Act
var actual = subject.GetPersons(wurAccounts);
//Assert
actual.Should()
.NotBeNull()
.And.HaveCount(wurAccounts.Length);
}
public class PersonSynchronizer {
private IUnitOfWork unitOfWork;
private ISession session;
public PersonSynchronizer(IUnitOfWork uow) {
this.unitOfWork = uow;
this.session = unitOfWork.Session;
}
public Dictionary<string, Person> GetPersons(IEnumerable<string> wurAccounts) {
var accounts = wurAccounts.ToList();
return this.session.Query<Person>()
.Where(x => accounts.Contains(x.WurAccount))
.ToDictionary(x => x.WurAccount);
}
}
public class Person {
public string DisplayName { get; set; }
public string Email { get; set; }
public string WurAccount { get; set; }
}
public interface IUnitOfWork : IDisposable {
ISession Session { get; }
IQueryable<T> Query<T>();
void BeginTransaction();
void Commit();
void Rollback();
}
public interface ISession {
IQueryable<T> Query<T>();
}
}
上面的代码段在测试时按预期传递。
我建议检查是否有任何可能与默认Linq Extensions冲突的NHibernate扩展方法,导致遇到问题。