2015-10-08 1 views
3

Я пытаюсь использовать NSubstitute, чтобы высмеять возвращаемое значение из подстановки, но я не могу получить замену, чтобы вернуть правильное значение, потому что сигнатура метода использует Func.Mock результат от Func с NSubstitute

Я видел эти вопросы, но не могу заставить его работать с моим Func.

Mocking Action<T> with NSubstitute

Mocking out expression with NSubstitute

интерфейс Я пытаюсь издеваться это (несколько simplyfied):

public interface IOrgTreeRepository<out T> where T : IHierarchicalUnit 
{ 
    T FirstOrDefault(Func<T, bool> predicate); 
} 

Я подставляя его NSubstitute следующим образом:

_orgTreeRepository = Substitute.For<IOrgTreeRepository<IOrganizationUnit>>(); 

А потом я пытаюсь изменить обратное v ALUE так:

_orgTreeRepository.FirstOrDefault(Arg.Is<Func<IOrganizationUnit, bool>>(x => x.Id== _itemsToUpdate[0].Id)).Returns(existingItems[0]); 

Но это просто возвращает прокси-объект вместо моего определенного объекта в existingItems.

Однако, благодаря другим вопросам, мне удалось заставить это работать, но это мне не помогает, так как мне нужен конкретный элемент каждый раз.

_orgTreeRepository.FirstOrDefault(Arg.Any<Func<IOrganizationUnit, bool>>()).Returns(existingItems[0]); // Semi-working 

Я предполагаю, что он рассматривает выражение лямбда как своего рода абсолютную ссылку и поэтому пропускает ее? Можно ли каким-либо образом высмеять возвращаемое значение?

ответ

4

Как вы правильно догадались, NSubstitute просто использует ссылочное равенство здесь, поэтому, если у вас нет ссылки на тот же предикат (который иногда является опцией), тогда вам нужно будет сопоставить любой вызов (или .ReturnsForAnyArgs) или использовать примерный вид согласования для проверки функции передается в

в качестве примера приближенного соответствия:.

[Test] 
public void Foo() { 
    var sample = new Record("abc"); 
    var sub = Substitute.For<IOrgTreeRepository<Record>>(); 
    sub.FirstOrDefault(Arg.Is<Func<Record,bool>>(f => f(sample))).Returns(sample); 

    Assert.AreSame(sample, sub.FirstOrDefault(x => x.Id.StartsWith ("a"))); 
    Assert.AreSame(sample, sub.FirstOrDefault(x => x.Id == "abc")); 
    Assert.Null(sub.FirstOrDefault(x => x.Id == "def")); 
} 

Здесь мы погасили FirstOrDefault вернуть sample всякий раз, когда Func<T,bool> возвращается true для sample (используется другая перегрузка Arg.Is, которая принимает выражение, а не значение переданного аргумента).

Это проходит тест для двух разных предикатов, потому что sample удовлетворяет обоим из них. Он также передает последнее утверждение, поскольку он не возвращает sample для функции, которая проверяет наличие другого идентификатора. Мы не можем гарантировать, что в этом случае был использован конкретный предикат, но этого может быть достаточно. В противном случае мы зациклились на контрольном качестве на Func.

Надеюсь, это поможет.

+0

Ну, это отличное решение моей проблемы. Большое спасибо. – smoksnes

+0

Я бы никогда не догадался! Большое спасибо. – Invvard

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