简体   繁体   English

MOQ 创建抽象类的 Mock 返回 null

[英]MOQ Creating a Mock of an abstract class returns null

Firstly, I understand that the title of my question doesn't really suit the question;首先,我明白我的问题的标题并不适合这个问题; I just wasn't sure what the title should've been.我只是不确定标题应该是什么。

It is to the best of my knowledge that when creating a mock of an abstract class with MOQ if the creation of the object fails (due to exception handling or something else) the creation of the mock will simply return null.据我所知,在创建具有 MOQ 的抽象类的模拟时,如果对象的创建失败(由于异常处理或其他原因),则模拟的创建将简单地返回 null。

In my case, I wish to check if an ArgumentNullException has been thrown within the constructor.就我而言,我希望检查构造ArgumentNullException是否抛出了ArgumentNullException But instead my test fails due to what I've stated above and the actual result is null , not ArgumentNullException但是由于我上面所说的,我的测试失败了,实际结果是null ,而不是ArgumentNullException

public abstract class SomeClass
{
    public SomeClass(ISomeDependency someDependency)
    {
        if (someDependency == null)
        {
            throw new ArgumentNullException(nameof(someDependency));
        }

        this.someDependency = someDependency;
    }
}
public sealed class LogHandlerTests
{
    [Test]
    public void Constructor_Test_Should_Throw_ArgumentNulLException_When_SomeDependency_Is_Null()
    {
            Assert.Throws<ArgumentNullException>(() => new Mock<SomeClass>(null));
    }
}

No real need to use MOQ here.没有真正需要在这里使用最小起订量。

Sometimes it helps to keep it simple and create a derived class to satisfy the desired behavior.有时它有助于保持简单并创建派生类以满足所需的行为。

For example例如

public sealed class LogHandlerTests {

    private class Subject: SomeClass {
        public Subject(): base (null) { //<-- SHOULD THROW
            //...
        }
    }

    [Test]
    public void Constructor_Test_Should_Throw_ArgumentNulLException_When_SomeDependency_Is_Null() {
        Assert.Throws<ArgumentNullException>(() => new Subject());
    }
}

Instead of using new Mock<SomeClass>(null) you want to use new Mock<SomeClass>(null).Object because the constructor is only invoked the first time you use the mocked object.而不是使用new Mock<SomeClass>(null)你想使用new Mock<SomeClass>(null).Object因为构造函数只在你第一次使用new Mock<SomeClass>(null).Object对象时被调用。 You'll then end up having a TargetInvocationException because Moq uses reflection to achieve Mocking.然后您最终会遇到TargetInvocationException因为 Moq 使用反射来实现 Mocking。 This means you probably need a code similar to这意味着您可能需要一个类似于

[TestClass]
public class Test
{
    [TestMethod]
    public void MyTestMethod()
    {
        Exception caughtException = null;
        try
        {
            var test = new Mock<SomeClass>(null).Object;
        }
        catch (Exception ex)
        {
            caughtException = ex;
        }

        Assert.IsInstanceOfType(caughtException.InnerException, typeof(ArgumentNullException));
    }
}

public abstract class SomeClass
{
    ISomeDependency someDependency;

    public SomeClass(ISomeDependency someDependency)
    {
        if (someDependency == null)
        {
            throw new ArgumentNullException(nameof(someDependency));
        }

        this.someDependency = someDependency;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM