【问题标题】:Unit Testing NHibernate Repository单元测试 NHibernate 存储库
【发布时间】:2012-02-06 01:40:48
【问题描述】:

我在对我的 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);
}

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

任何想法我哪里出错了?如果我可以提供更多信息,请告诉我...

【问题讨论】:

  • repository 实例似乎没有注入到EmployeeService。你是如何构建EmployeeService的?
  • 嗨 Jonathon,我将它注入到测试夹具 SetUp 方法中:EmployeeService = new EmployeeService(repository);
  • 您发布的测试的第一行显示了repository 的定义。这发生在调用 SetUp 方法之后,这意味着未使用模拟。也许将您的 SetUp 方法添加到上面。
  • 更新包括测试设置方法:)
  • 请注意确定是否是您的问题,但您发布的存储库方法与您正在模拟的方法不同。

标签: .net unit-testing nhibernate


【解决方案1】:

我想我已经设法使用 NUnit 和 RhinoMocks 获得了您正在尝试做的工作示例。这个测试所做的只是检查 FindBy 是否被调用,我认为你需要一个集成测试来覆盖正在应用的正确过滤器表达式。

IRepository

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

登录服务

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));
    }
}

【讨论】:

  • 感谢您的所有帮助伙伴,我想我会在尝试测试存储库方法而不是逻辑时走错路:)
猜你喜欢
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
  • 1970-01-01
相关资源
最近更新 更多