API NSubstitute полагается на вызов метода для настройки его на Returns
или проверки Received()
вызовов, что означает, что для стандартного использования мы можем работать только с вызовами, которые могут быть вызваны через публичный API (за исключением protected
и private
членов). С частью вашего вопроса abstract
нет проблем; нормально использовать NSubstitute с доступными abstract
членами.
Несмотря на то, что C # по своей природе не позволяет нам напрямую взаимодействовать с protected
участниками, NSubstitute все еще записывает вызовы, сделанные этим участникам. Мы можем проверить это, используя "неофициальное" .ReceivedCalls()
расширение:
public abstract class ItemsRepository {
public virtual void Add(int i) { ItemAdded(); }
protected abstract void ItemAdded();
}
public class Fixture {
[Fact]
public void CheckProtectedCall() {
var sub = Substitute.For<ItemsRepository>();
sub.When(x => x.Add(Arg.Any<int>())).CallBase();
sub.Add(42);
var called = sub.ReceivedCalls().Select(x => x.GetMethodInfo().Name);
Assert.Contains("ItemAdded", called);
}
}
Другие варианты включают создание производного класса (как указал @Nkosi) или создание элемента internal
вместо protected
и использование InternalsVisibleTo
, чтобы сделать элемент доступным для вашего тестового кода (если вы делаете последний Я рекомендую установить NSubstitute.Analyzer , чтобы убедиться, что он настроен правильно).