Кроме смоделированного вызова метода фактические методы для ложного объекта - PullRequest
1 голос
/ 07 февраля 2020
IFoo
{
    string abc();
    string def();
}

Foo: IFoo
{
    string abc()
    {
        def();
    }

    string def()
    {
    }
}

Mymainclass
{
    private IFoo _foo;

    public Mymainclass():this(new Foo())
    {}

    public Mymainclass(IFoo foo)
    {
        _foo = foo;
    }

    string mainmethod()
    {
        _foo.abc();
    }
}

[TestClass]
public class Mymainclasstester
{
    Mymainclass mainclass;
    Mock<IFoo> mifoo;

    [TestInitialize]
    public void TestInitialize()
    {
        mifoo = new Mock<IFoo>();
        mifoo.Setup(x => x.def(It.IsAny<string>())).Returns("abc");
        mainclass = new Mymainclass(mifoo.Object);
    }

    [TestMethod]
    public void testmethod()
    {
        mainclass.mainmethod();
    }
}

Как видно выше в testmethod (), я вызываю mainmethod () класса Mymainclass, который inturn вызывает ab c () класса Foo. ab c () вызывает def (), как видно из приведенного выше кода. Я издевался только по def (). Когда вызов сделан из testmethod (), я хочу сделать фактический вызов ab c () из Foo, и только mock def ().

В настоящее время с этой реализацией ab c () не выполняется.

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

1 Ответ

1 голос
/ 07 февраля 2020

Вы не можете заархивировать то, что вы хотите, используя interface. На самом деле, вы можете, но насмешливо abc вызвать def, что немного неловко:

mock.Setup(x => x.abc()).Returns(() => mock.Object.def());

Хотя я не вижу в этом смысла, вместо этого вы можете просто высмеивать abc .. .


Единственный способ архивировать то, что вы хотите, используя макет, это использовать актуальную функцию class и Callbase.

public class Foo : IFoo
{
    public virtual string abc() //methods have to be virtual to be mockable
    {
        return def();
    }

    public virtual string def() //methods have to be virtual to be mockable
    {
        return "123";
    }
}

//setup
var mock = new Mock<Foo>();
mock.Setup(x => x.def()).Returns("abc");
mock.Setup(x => x.abc()).CallBase();

mock.Object.abc(); // "abc"

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

...