Moq Framework Func - PullRequest
       1

Moq Framework Func

5 голосов
/ 10 февраля 2012

Я новичок в Moq и TDD, и я пытаюсь настроить метод на интерфейсе репозитория.

Вот полная история.

У меня есть класс сущности домена под названием Tenant со свойством BusinessIdentificationNumber

public class Tenant:EntityBase<Tenant>,IAggregateRoot
{
 ...
 public string BusinessIdentificationNumber {get;set;}
 ...
}

Далее у меня есть хранилище для этой сущности, интерфейс которого похож на

public interface IRepository<T>
{
 ...
 T FindBy(Func<T,bool> func);
 ...
}

там, где проблема, я использую службу домена, которая содержит правила для создания арендатора и похожа на

public class TenantCreationService:ITenantCreationService
{
    public TenantCreationService(IRepository<Tenant> tenantRepository){...}

    public void CreateTenant(Tenant tenant)
    {
        //from here there is call to IRepository<Tenant>.FindBy(funcMethod);
    }
}

И в модульном тестировании, где я тестирую TenantCreationService, я высмеиваю репозиторий, переданный конструктору, но я хотел бы протестировать функцию:

  • если арендатор с BusinessIdentificationNumber уже существует в хранилище или сеансе, его следует вернуть.

Так что я пытался сделать это как

repositoryMock.Setup(x=>x.FindBy(It.Is<Tenant>(t=>t.BusinessIdentificationNumber
   == _tenantInTest.BusinessIdentificationNumber))).Returns(_tenantInTest) 

но он не компилируется. Вы знаете, что я хочу сделать?

EDIT: когда я пытаюсь скомпилировать фрагмент ниже

repositoryMock.Setup(e => e.FindBy(t => t.BusinessNumber == _validTenant.BusinessNumber)).Returns(
                _validTenant);

я получаю исключение

Unsupported expression: t => (t.BusinessNumber == value(DP.IPagac.UnitTests.DP.IPagac.Module.TenantManagement.TenantDomainServiceTests)._validTenant.BusinessNumber)

Ответы [ 2 ]

6 голосов
/ 10 февраля 2012

Я думаю, что вы пытаетесь достичь этого (убрали некоторые вещи, которые были посторонними, например, и создали ITenent, чтобы его можно было смоделировать динамически):

[TestFixture]
public class Test
{
    [Test]
    public void CreateTenentAlreadyExistsTest()
    {
        var tenentMock = new Mock<ITenant>();
        var repoMock = new Mock<IRepository<ITenant>>();

        tenentMock.Setup(t => t.BusinessIdentificationNumber).Returns("aNumber");

        repoMock.Setup(r => r.FindBy(It.Is<System.Func<ITenant, bool>>(func1 => func1.Invoke(tenentMock.Object)))).Returns(tenentMock.Object);

        var tenantCreationService = new TenantCreationService(repoMock.Object);

        tenantCreationService.CreateTenant(tenentMock.Object);

        tenentMock.VerifyAll();
        repoMock.VerifyAll();
    }
}

public interface ITenant
{
    string BusinessIdentificationNumber { get; set; }
}

public class Tenant : ITenant
{
    public string BusinessIdentificationNumber { get; set; }
}

public interface IRepository<T>
{
    T FindBy(System.Func<T, bool> func);
}

public class TenantCreationService : ITenantCreationService
{
    private readonly IRepository<ITenant> _tenantRepository;

    public TenantCreationService(IRepository<ITenant> tenantRepository)
    {
        _tenantRepository = tenantRepository;
    }

    public void CreateTenant(ITenant tenant)
    {
        var existingTenant =
            _tenantRepository.FindBy(t => t.BusinessIdentificationNumber == tenant.BusinessIdentificationNumber);

        if (existingTenant == null)
        {
            //do stuff
        }
    }
}

public interface ITenantCreationService
{
    void CreateTenant(ITenant tenant);
}
0 голосов
/ 10 февраля 2012

"если арендатор с BusinessIdentificationNumber уже существует в хранилище или сеансе, его следует вернуть." - из этого описания теста я понял, что такое поведение вы должны тестировать в классе репозитория, а не в классе обслуживания

В модульном тестировании сервисов вы не должны тестировать слой доступа к данным, я имею в виду ваши репозитории, Вы должны просто убедиться, что метод хранилища FindBy был вызван. и я предлагаю создать ITenantRepositry, который является производным от интерфейса IRepository и от базового класса Repostiry.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...