单元测试NHibernate存储库

时间:2012-02-06 01:40:48

标签: .net unit-testing nhibernate

我在对NHibernate存储库方法进行单元测试时遇到了一些困难,主要是因为他们正在传递一个表达式并返回一个IQueryable。

以下是其中一个存储库方法:

public TEntity FindBy<TEntity>(Expression<Func<TEntity, bool>> expression)
{
    return Session.Query<TEntity>().SingleOrDefault(expression);
}

这是一个相关的方法调用:

public Employee Login(string username, string password)
{
    return Repository.FindBy<Employee>
    (
        e => e.Active 
            && e.Username.ToLower() == username.ToLower()
            && e.Password == password
    );
}

以及相关的单元测试:

[Test]
public void ForMatchingEmployeeUsernameAndPassword_ReturnsEmployee()
{       
    var employee = HelperEmployee.GetEmployee();

    repository.Setup(x => x.FindBy(It.IsAny<Expression<Func<Employee, bool>>>())).Returns(employee);

    var result = EmployeeService.Login(employee.Username, employee.Password);

    Assert.IsNotNull(result);
    Assert.IsInstanceOf<Employee>(result);
    Assert.AreSame(employee, result);
}

测试设置方法:

[SetUp]
public void Init()
{
    mock = new Mock<IRepository>();
    repository = mock.Object;
    EmployeeService = new EmployeeService(repository);
}

当我尝试模拟存储库方法时出现问题,我将逻辑传递给它,而不是在它返回的结果上执行逻辑。所以很难测试我的逻辑,因为我忽略它并返回我在模拟中设置的任何东西。

我出错的任何想法?如果我能提供更多信息,请告诉我......

1 个答案:

答案 0 :(得分:1)

我想我已经设法使用NUnit和RhinoMocks获得了你正在尝试做的工作样本。所有这个测试都在检查FindBy是否被调用,我认为您需要进行集成测试以涵盖正在应用的正确过滤器表达式。

<强> IRepository

public interface IRepository
{
    TEntity FindBy<TEntity>(Expression<Func<TEntity, bool>> expression);
}

<强> login服务

public class LoginService
{
    private readonly IRepository _repository;

    public LoginService(IRepository repository)
    {
        _repository = repository;
    }

    public Employee Login(string username, string password)
    {
        return _repository.FindBy<Employee>
        (
            e => e.Active
                && e.Username.ToLower() == username.ToLower()
                && e.Password == password
        );
    }
}

<强> LoginServiceTests

[TestFixture]
class LoginServiceTests
{
    private IRepository _repository;
    private LoginService _loginService;

    [SetUp]
    public void Setup()
    {
        _repository = MockRepository.GenerateMock<IRepository>();
        _loginService = new LoginService(_repository);
    }

    [Test]
    public void Login_should_return_employee()
    {
        var expected = new Employee { Username = "Jon" };

        _repository.Expect(f => f.FindBy(Arg<Expression<Func<Employee, bool>>>.Is.Anything)).Return(expected);

        var result = _loginService.Login("jon", "mysecret");

        Assert.That(result, Is.InstanceOf<Employee>());
        Assert.That(result, Is.EqualTo(expected));
    }
}