80% ошибок вносятся на этапе проектирования.
Остальные 80% вводятся на этапе кодирования.
(Это мнение было вдохновлено чтением ответа Димы Маленко. «Разработка на 80% связана с дизайном и 20% - с кодированием», да. «Это даст код с почти нулевыми ошибками», нет.)
Ответ находится в сообщении об исключении:
... При промежуточных вызовах в настройке поддерживаются только обращения к свойствам ...
Попробуйте следующее:
var user = new Mock<MemberShipUser>();
user.SetupGet(x => x.PasswordQuestion).Returns("Password");
membershipMock.Setup(m => m.GetUser("test", false)).Returns(user.Object);
Я полагаю, что промежуточный вызов, на который он ссылается, следующий: m.GetUser ("test", false)
, поскольку за ним следует .PasswordQuestion
. В нем говорится: вы не можете использовать метод в качестве промежуточной заглушки, только свойство. Этот конкретный фреймворк, кажется, поддерживает промежуточные заглушки (то есть создает XY в определении заглушки, обратите внимание на точку), но большинство других нет.
Заглушки не являются волшебными, все, что они могут сделать, это перехватить ваши вызовы и заменить возвращенный результат с предоставленным вами значением. В вашем случае ваша заглушка GetUser должна возвращать имитацию пользователя с заглушкой PasswordQuestion, чтобы вернуть «Пароль».
Еще одна проблема с вашим кодом заключается в том, что вы напрямую насмехаетесь над MembershipProvider. Как работает большинство фреймворков, если вы имитируете интерфейс, они динамически генерируют класс, реализующий его, а когда вы имитируете класс, они генерируют класс, который наследуется от него и переопределяет любые виртуальные методы. Однако, если метод не виртуальный, он не может его переопределить, поэтому вы можете наблюдать смешанное поведение. Я предлагаю вам посмотреть, есть ли такой интерфейс, как IMembershipProvider, и если да, используйте его в своем коде вместо конкретного класса.