13

我们对项目中的各种命令进行了很多 CanExecute 测试。当我们使用 Visual Studio 测试或 AxoCover 时,所有测试都正确通过。

我们尝试在执行“CanExecute”之前添加一些先前的对象初始化,有时它会起作用(或者我们认为)。

testedViewModel.Object.InEditMode = inEditMode;

我有一个测试:

[TestCase(true, true, TestName = "Command_InEditMode_CanExecute")]
[TestCase(false, false, TestName = "Command_NotInEditMode_CannotExecute")]
public void CommandCanExecute(bool inEditMode, bool expectedResult)
{
    var testedViewModel =
        new Mock<SomeViewModel>(inEditMode)
        {
            CallBase = true
        };

    testedViewModel.Setup(x => x.InEditMode).Returns(inEditMode);

    Assert.AreEqual(expectedResult, testedViewModel.Object.Command.CanExecute(null));
}

有时(不总是)当 Jenkins 进行构建和运行单元测试时,一些可以执行的测试失败并显示消息:

MESSAGE:
  Expected: True
  But was:  False

+++++++++++++++++++  
STACK TRACE:
   at Project.CommandCanExecute(Boolean inEditMode, Boolean expectedResult)

问题是这种情况只发生在 Jenkins 上,而且非常不确定。

编辑:

好的,还要考虑一件事。属性 InEditMode 放置在 SomeModelView 的基父类中。

我在示例中为您合并了代码。

public BaseViewModel 
{
    public virtual bool InEditMode {get; set;}
}

public SomeViewModel : BaseViewModel
{
    public SomeViewModel () : base ()
    {

    }

    public ICommand Command { get; set; }

    public virtual void RegisterCommands()
    {
        Command = new RelayCommand(/*Do something*/, () => InEditMode);
    }
}

我们认为这可能是相关的,该对象认为在基类初始化完成之前已初始化。但这很难用詹金斯检查。


解决方案

我创建了一个属性类:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Assembly, AllowMultiple = true)]
public class GarbageCollectorDisabler : Attribute, ITestAction
{
    public void BeforeTest(ITest test)
    {
        GC.TryStartNoGCRegion(2048 * 4096);
    }

    public void AfterTest(ITest test)
    {
        GC.EndNoGCRegion();
    }

    public ActionTargets Targets => ActionTargets.Test;
}

然后我可以为每个“CanExecute”测试这个属性:

[GarbageCollectorDisabler]
[TestCase(TestName = "SomeTest_InEditMode_CanExecute")]
public void SomeTestCanExecute()
{}
4

1 回答 1

1

对我来说闻起来像是垃圾收集问题。尽管代码示例不完整(在哪里调用?),但我在您的示例中没有看到任何让我兴奋的东西,RegisterCommands因此可能缺少一些关键的东西。

请参阅 的来源RelayCommand.CanExecute()。它对您传入的操作进行弱引用,一旦该操作被收集,CanExecute就会返回false有关发生这种情况的示例, 请参见我的答案。

我重申@Nkosi 的评论,创建一个最小的示例,而不是向我们展示点点滴滴。

于 2019-06-12T20:18:58.730 回答