2013-05-28 2 views
0

Я тестирую службу в рамках.Тестирование службы с использованием объектов mock-репозитория

Чтобы инициализировать службу, я использую mock объекты репозитория.

ServiceTest.cs

private IRepository _repository; 
private IService _service; 
private List<Object> _objects; 

[TestInitialize] 
public void Initialize() 
{ 
    _repository = new Mock<IRepository>().Object; 

    _service = new Service(repository); 

    _objects = new List<Object>() 
    { 
     new Object { Name = "random", ID = 1 }, 
     new Object { Name = "not so random", ID = 1}, 
     new Object { Name = "random", ID = 2 }, 
     new Object { Name = "not so random", ID = 2} 
    }; 

    //attempt at mocking the repository 
    _repository.Setup(r => r.GetObjects(It.IsAny<string>(), It.IsAny<int>())).Returns(_objects.Where(o => o.Name == _objects.Name && o.ID == _objects.ID).ToList()); 
} 

[TestMethod] 
public void GetObjects_ReturnObjectsList() 
{ 
    //Arrange 
    var name = "random"; 

    //Act 
    var objects = _service.RetrieveObjects(name, 2); 

    //Assert 
    Assert.AreEqual(name, objects.Single().Name); 
} 

Однако, когда я протестировать сервис, я получаю ArgumentNullExceptions. Переменные, установленные для метода репозитория, возвращают null и, в конечном счете, вызывают ошибку при запуске бизнес-логики.

Service.cs

public List<Objects> RetrieveObjects(string name, int id) 
    { 
     var getObjects = repository.GetObjects(name, id); //getObjects return null 

     DoLogic(getObjects); //ArgumentNullException is thrown here 

     return getObjects; 
    } 

Я посмотрел информацию на насмешливые хранилищах, но кажется, что у меня будет много для настройки только для тестирования. Мне интересно, стоит ли установка.

Почему я получаю ArgumentNullExceptions? Есть ли способ протестировать методы, которые вызывают репозитории?

+0

Что вы пытаетесь протестировать? Сервис или репозиторий? Вы издеваетесь над репозиторием и утверждаете, что он возвращает ?! –

+0

@ lucky3 Упс, я имел в виду сервис. –

ответ

1

Вам просто нужно установить, что испытывается так в вашем организовать что-то вроде:

var repository = new Mock<IRepository>(); 
repository.Setup(x => x.GetObjects(It.IsAny<string>()).Returns("whatever getobjects should be returned, maybe a mock object or string"); 
var service = new Service(repository.Object()); 
//Continue your test 
+0

См. Обновление в моем вопросе. Переменная 'repository' устанавливается в объект' IRepository', а не var. 'new Mock ()' не работает с 'IRepository'. –

+0

Игнорируйте первую строку и просто используйте метод макета для подделки вызова GetObjects, а затем передайте объект репозитория службе. – ianaldo21

+0

Имеет ли значение, что вызов репозитория находится в другом файле '.cs' вообще? Я установил mock репозиторий и все еще получаю 'null'. См. Обновление. –

1
var entity1 = new MyEntity(); 
var entity2 = new MyEntity(); 
var entities = new List<MyEntity>{entity1, entity2}; 

var mockRepository = new Mock<IRespository>(); 

mockRepository.Setup(r => r.GetObjects("some param")).Returns(entities); 

var service = new Service(mockRepository.Object); 

service.DoWork("some param"); 
//continue the test 
+0

Имеет ли значение, что вызов репозитория находится в другом файле '.cs' вообще? Я установил mock репозиторий и все еще получаю 'null'. См. Обновление. –

+0

Это не имеет значения. Осмотрите свой DoLogic-метод, что-то не так. Приведенная выше настройка должна работать и возвращать правильные данные. Убедитесь, что «param» также подходит. –

+0

Когда 'getObjects' передано в DoLogic, это' null'. Это было до этого факта. Пока не достигнут прогресса в этом отношении. Классы репозитория прошли тщательное тестирование модулей, и теперь я тестирую службы в рамках. –

2

Вы должны проверить свой SUT (предмет испытываемого) в изоляции. Не пытайтесь издеваться над существующими классами, используйте только интерфейсы. Таким образом, вы не будете зависеть от других объектов, которые потенциально могут быть ошибочными. Часто вы не сможете настраивать обратные вызовы и возвраты существующих классов, используемых как mocks. Стыковые интерфейсы позволяют вам контролировать и прогнозировать возвращаемые значения.

Так что в вашем конкретном случае, вы должны сделать, как @ ianaldo21 предложил, я бы просто изменить первую строку на:

var repository = new Mock<IRepository>(); 

, а затем выполнить установку, и передать repository.Object к службе.

Вместо того чтобы утверждать состояние SUT, вы должны проверить поведение и взаимодействие SUT с другими объектами. Таким образом, у вас могло бы быть что-то вроде этого:

repository.Verify(x => x.GetObjects("test")); 

Таким образом, для тестирования вам часто требуется гораздо меньше настроек.

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