如何在setter中测试私有方法c#

时间:2017-09-07 17:33:45

标签: c# testing

我在测试期间遇到问题。我有一个类和属性,如这些

 public class ViewModel {

 ....

   public string Person 
    {
        get
        {
            return _person;
        }
        set
        {
            if (_person != value)
            {
                _person = value;
                RefreshStrategy();
                OnPropertyChanged();
                Somefield = string.Empty;
            }
        }
    }

   public BindingList<string> Strategies
    {
        get
        {
            return _lstStrategies;
        }
    }

现在,RefreshStrategy是一个包含多个其他对象的巨大方法,它从数据库中获取一些策略,并根据所选的Person更新_lstStrategies。现在一切都在运行时工作正常但是当我尝试测试它时,我遇到了一个问题:

[TestClass]
public class ViewModelTest 
{

    private ViewModel _viewobj; 

    public ViewModelTest()
    {

        _viewobj = new ViewModel();
    }


    [TestMethod]
    public void TestStrategies()
    {
       _viewobj.Person = "Test";

        Assert.AreEqual("AAAA", _viewobj.Strategies[0]); 

    }

 private void RefreshStrategies()
    {
         Logger.log(Logger.INFO, $"GOT STRATEGIES");
        // Reload these default options every time the form loads, in case    some applications settings have been changed
        if (String.IsNullOrEmpty(Trader) && !SettingsMgr.IsCompositePortfolio)
        {
            Person = Utility.SettingsMgr.PORTFOLIO_CODE;
        }
        if (!String.IsNullOrEmpty(Person))
        {

            string fund = _portfolios.Where((tt) => tt.PersonId == Person).Select(tt => tt.Fund).FirstOrDefault();
            if (!string.IsNullOrEmpty(fund))
            {
                fund = "X";
            }
            var profitCenters = new List<ProfitCenter>();
            try
            {
                Logger.log(Logger.INFO, $"Try to load strategies for {Person} {fund}");

                var pci = DataMgr.getInstance().GetProfitCenterInfo(Person, fund);
                Logger.log(Logger.INFO, $"HERE !!!");
                profitCenters = pci?.profitCenters;

            }
             ......

      }

当我设置Person = "Test"时,显然会调用RefreshStrategy()但是在所有对象中都是null并且它引发异常“...尝试取消引用空对象引用”。开头的简单记录器正在提高,如果我将它评论出来,则Utility.Setting正在等待

如果我对这个类做了一个简单的测试,比如测试一个简单的变量正在传递,这告诉我测试项目中的所有引用都没问题。

我做错了什么?我是否嘲笑整个方法?如果是,如果它是私人的?

1 个答案:

答案 0 :(得分:1)

这是一种方法:

public interface IStrategyManager 
{
    void RefreshStrategy();
}
public class StrategyManager : IStrategyManager
{
    public void RefreshStrategy()
    {
         // Doesn't matter what is in here.
    }
}
public class ViewModel {
    public IStrategyManager StrategyManager = new StrategyManager();

   public string Person 
    {
        get
        {
            return _person;
        }
        set
        {
            if (_person != value)
            {
                _person = value;
                StrategyManager.RefreshStrategy();
                OnPropertyChanged();
                Somefield = string.Empty;
            }
        }
    }
}

你只需要嘲笑这个属性:

private ViewModel _viewModel;

[Test]
public void Test()
{
    _viewModel = new ViewModel
    {
        StrategyManager = new Mock<IStrategyManager>().Object,
        Person = "whatever"
    };

}

当然Dependency Injection会更好用,但我不知道你是否使用它。然后你可以用构造函数注入替换属性。

这也允许你有IStrategyManager的不同实现,这很好。这种方法的弱点是附加的类和接口。