2013-10-02 4 views
0

Я использую Moq в своих модульных тестах, и я не могу понять, почему мой тест терпит неудачу.Не удается найти, где мой макетный тест терпит неудачу

Вот ошибка я получаю

Moq.MockVerificationException: Следующие расстановок не были согласованы:
IGroupRepository г => r.Delete (It.Is (ит => um.Equals()))

Вот услуга, которую я пытаюсь проверить.

Сервис

public GroupService (IGroupRepository groupRepository) 
{ 
    _groupModelToViewModelMapper = new AutoMapper<GroupModel, GroupViewModel>(); 
    _groupViewModelToModelMapper = new AutoMapper<GroupViewModel, GroupModel>(); 
    _groupRepository = groupRepository; 
} 

public void Delete(GroupViewModel viewModel) 
{ 
    _groupRepository.Delete(_groupViewModelToModelMapper.BuildFrom(viewModel)); 
} 

Тест

[Test] 
public void FAILING_TEST() 
{ 
    // Setup the Mock GroupRepository 
    _groupRepository.Setup(r => r.Delete(It.Is<GroupModel>(um => um.Equals(_groupModel)))); 

    var groupService = new GroupService(_groupRepository.Object); 

    // execute 
    groupService.Delete(_groupViewModel); 

    // assert 
    _groupRepository.VerifyAll(); 
} 

То, что я не могу понять, если я Инжектируйте AutoMapper, тесты проходят. Я не вижу смысла вводить автоперенос, поскольку он в основном является взаимно однозначным, а модели обслуживания - это сопоставление.

Сервис

public GroupService(IGroupRepository groupRepository, 
        IAutoMapper<GroupViewModel, GroupModel> groupViewModelToModelMapper, 
        IAutoMapper<GroupModel, GroupViewModel> groupModelToViewModelMapper) 
{ 
    _groupModelToViewModelMapper = groupModelToViewModelMapper; 
    _groupRepository = groupRepository; 
    _groupViewModelToModelMapper = groupViewModelToModelMapper; 
} 

public void Delete(GroupViewModel viewModel) 
    { 
     _groupRepository.Delete(_groupViewModelToModelMapper.BuildFrom(viewModel)); 
    } 

Тест

[Test] 
public void PASSING_TEST() 
{ 
    // Setup the Mock GroupRepository 
    _groupRepository.Setup(r => r.Delete(It.Is<GroupModel>(um => um.Equals(_groupModel)))); 

    // Setup the Mock ModelMapper 
    _viewModelToModelMapper.Setup(vmm => vmm.BuildFrom(It.Is<GroupViewModel>(u => u.Equals(_groupViewModel)))) 
          .Returns(_groupModel); 

    var groupService = new GroupService(_groupRepository.Object, _viewModelToModelMapper.Object, _modelToViewModelMapper.Object); 

    // execute 
    groupService.Delete(_groupViewModel); 

    // assert 
    _groupRepository.VerifyAll(); 
    _viewModelToModelMapper.VerifyAll(); 
} 

Кроме того, если это действительно, вот Тестовое.

private GroupModel _groupModel; 
private List<GroupModel> _groupModels; 
private GroupViewModel _groupViewModel; 
private List<GroupViewModel> _groupViewModels; 
private Mock<IGroupRepository> _groupRepository; 
private Mock<IAutoMapper<GroupViewModel, GroupModel>> _viewModelToModelMapper; 
private Mock<IAutoMapper<GroupModel, GroupViewModel>> _modelToViewModelMapper; 


[SetUp] 
public void SetUp() 
{ 
    _groupModel = new GroupModel(); 
    _groupModels = new List<GroupModel>(); 
    _groupViewModel = new GroupViewModel(); 
    _groupViewModels = new List<GroupViewModel>(); 
    _groupRepository = new Mock<IGroupRepository>(); 
    _viewModelToModelMapper = new Mock<IAutoMapper<GroupViewModel, GroupModel>>(); 
    _modelToViewModelMapper = new Mock<IAutoMapper<GroupModel, GroupViewModel>>(); 

} 

Может ли кто-нибудь помочь мне получить эту издевательскую штуку?

+0

Случайная догадка - ваш 'Equals' не сравнивает объекты по значению и' um => um.Equals (_groupModel) 'терпит неудачу, когда модель сгенерирована вместо явно возвращенного, как при прохождении теста. –

+0

Итак, зачем это передавать, если я вставляю modelMappers, но не передаю, если я создам их в конструкторе службы? –

+0

'_groupModel.Equals (_groupModel) 'истинно для сравнения по умолчанию по умолчанию (это то, что происходит, когда вы добавляете mapper, который просто возвращает _groupModel), но' _groupModel.Equals (new Model (fromSomeData)) 'всегда будет вызывать сравнение указателей по умолчанию ... –

ответ

1

Когда я издевался над всем, включая AutoMapper, он был достаточно хорош, чтобы использовать сравнение ссылок.

_groupRepository.Setup(r => r.Delete(It.Is<GroupModel>(um => um.Equals(_groupModel)))); 

Теперь, когда мы на самом деле, используя в AutoMapper не издевается его и инъекционные его, я должен был сделать сравнение стоимости.

_groupRepository.Setup(r => r.Delete(It.Is<GroupModel>(um => um.Id == groupId))); 

Решение этой проблемы.

+0

Это именно то, что я имел в виду ... Заметьте, что у lazyberezovsky есть хорошее предложение, которое может быть тем, что вам нужно в остальной части проекта (если вы хотите обработать «GroupModel» больше например, значение типа) .Если это просто для насмешек - сравнение одного интересного свойства - совершенно правильный подход. –

+0

Спасибо @AlexeiLevenkov ... он просто немного подумал. Я слишком долго смотрел на экран. –

2

Просто переверните EqualsGetHashCode) вашего класса GroupModel и ваш тест пройдет. По умолчанию Equals использует сравнение, основанное на ссылках на объекты. Таким образом, у вас есть два разных экземпляра (_groupModel и один построенный с помощью mapper). Equals возвращает false.

В вашем примере вы сравниваете точно такой же экземпляр _groupModel, поэтому Equals возвращает true.

+0

Что может «переопределенные« Equals »и« GetHashCode »выглядят? –

+1

@ChaseFlorell Equals должны реализовывать логику обработки экземпляров как равную - это может быть простое сравнение id или сравнение всех полей. [Генерация кода хэш-кода несколько сложнее] (http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode), когда вы используете несколько значений для сравнения в Equals (если вы используете только id для equ als, то вы можете использовать id.GetHashCode для хеш-кода объекта). –

Смежные вопросы