简体   繁体   English

类依赖于基类的受保护属性时的单元测试

[英]Unit test when class has dependency on protected property of base class

public class MyBaseClass
{
    protected void OnSomeEvent(EventContext context)
    {
         SomeType  = _someService.DoSomeLogic(context);
    }

    public SomeType SomeType { get; private set; } 
}

MyBaseClass works some magic to initialise a public property value when an event is triggerd in the process pipline. 当在过程管线中触发事件时, MyBaseClass发挥一些魔力来初始化公共属性值。

public class MyClass : MyBaseClass
{
    public string Foo()
    {
        if (SomeType.SomeLogic())
            throw new InvalidOpertaionException();

        return "huzzah";
    }
}

The flow in other classes depends on SomeType being initialised. 其他类中的流程取决于要初始化的SomeType

How can I unit test MyClass.Foo() ? 如何对MyClass.Foo()单元测试?

[TestMethod]
public void Foo_ReturnsHuzzah()
{
    var result = new MyClass().Foo(); 
    Assert.IsHuzzah(result);   
}

_someService looks like an external dependency. _someService看起来像一个外部依赖项。 I would use Dependency Injection to make that external dependency injectable, and then use a mocking framework to inject something that returns state that will make the rest of your tests pass. 我将使用“依赖关系注入”使该外部依赖关系可注入,然后使用模拟框架注入一些返回状态的东西,该状态将使其余测试通过。

Then run the public method that ultimately invokes OnSomeEvent, and you can test the whole chain of processing 然后运行最终调用OnSomeEvent的公共方法,您可以测试整个处理链

This type of temporal coupling (the event must be raised before the call to Foo is valid) is often considered a design flaw so the first thing I would do is revisit the design to make sure what I have is right. 这种类型的时间耦合(必须在对Foo的调用有效之前必须引发事件)通常被认为是设计缺陷,因此,我要做的第一件事是重新设计以确保我所拥有的是正确的。

If you don't want to go that route, the easiest solution is to initialize SomeType with a Null Object implementation of SomeType like so... 如果您不想走这条路,最简单的解决方案是使用SomeType的Null Object实现来初始化SomeTypeSomeType所示:

class NullSomeType : SomeType
{
    public override bool SomeLogic() { return false; }
}

Then you default SomeType with the Null Object in the constructor. 然后,默认将SomeType与Null对象一起放在构造函数中。

public MyBaseClass()
{
   SomeType = new NullSomeType();
}

在调用Foo()之前设置SomeType

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

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