OrangeWombat
OrangeWombat

Reputation: 315

Mocking the NHibernate JoinAlias with Moq

I have the following repository code that will return a Company object based on an ID value, searching across the standard Company table and an additional table named ExternalCompany.

public Company FindByIdJoin(long id)
{
    ExternalCompany xcomp = null;
    return Session.QueryOver<Company>()
        .Where(p => p.ObjectId == id)
        .JoinAlias(p => p.ExternalCompanies, () => xcomp, JoinType.LeftOuterJoin)
        .SingleOrDefault<Company>();
}

The code returns values that I expect. However, the trouble I'm having is in writing a Moq unit test to handle the JoinAlias call.

In a simpler method, called FindById, the code is essentially the same except there is no line for JoinAlias. The unit test for this simpler method is:

[Test]
public void FindById_returns_Company_for_valid_Id()
{
    // Arrange
    Mock<IQueryOver<Company, Company>> mockQueryOver = new Mock<IQueryOver<Company, Company>>();

    mockQueryOver.Setup(x => x.Where(It.IsAny<Expression<Func<Company, bool>>>())).Returns(mockQueryOver.Object);
    mockQueryOver.Setup(x => x.SingleOrDefault()).Returns(fake_Company);

    // Act
    var result = _repository.FindById(fake_Company.ObjectId);

    // Assert
    Assert.IsNotNull(result);
    mockQueryOver.VerifyAll();
}

This test works and passes without a problem (fake_Company and _repository are defined elsewhere).

The problem is trying to put a test together for the FindByIdJoin call. I have tried using an additional Setup line like this (which goes between the Where and SingleOrDefault Setup lines):

mockQueryOver.Setup(x => x.JoinAlias(It.IsAny<Expression<Func<Company>>>(), It.IsAny<Expression<Func<ExternalCompany>>>(), JoinType.LeftOuterJoin)).Returns(mockQueryOver.Object);

The system tells me that "the best overloaded method match for IQueryOver ... has some invalid arguments."

So, I tried a few other variations on the Setup, but could not find a workable pattern.

My question is: what Setup arguments will work for JoinAlias so that I can properly test the FindByIdJoin method? Thanks!

Upvotes: 1

Views: 581

Answers (2)

Amol
Amol

Reputation: 4027

Shouldn't MOQ be used for behaviour tests? Such Data access tests seem to be state dependent and I think using mock objects for such a system under test is an overkill.

Upvotes: 0

Patrick Quirk
Patrick Quirk

Reputation: 23747

The particular overload of JoinAlias you are using is

IQueryOver<TRoot, TSubType> JoinAlias(
                                Expression<Func<TSubType, object>> path, 
                                Expression<Func<object>> alias, 
                                JoinType joinType);

So, your setup needs to match this. Based on how you setup your IQueryOver mock, the correct setup would then be

mockQueryOver.Setup(x => x.JoinAlias(
                               It.IsAny<Expression<Func<Company, object>>>(), 
                               It.IsAny<Expression<Func<object>>>(),
                               JoinType.LeftOuterJoin))
             .Returns(mockQueryOver.Object);

Upvotes: 1

Related Questions