断言在方法调用之前已分配值

本文关键字:分配 方法 调用 断言 | 更新日期: 2023-09-27 18:31:58

我正在使用 AAA 模式和 Rhino 模拟进行单元测试。我想断言在 DbContext 上调用 SaveChanges() 之前已经在实体上设置了特定值(电子邮件)。我有一个测试方法,看起来像这样:

protected override void Arrange()
{
    base.Arrange();
    _itemToUpdate = new FooEntity();
}
protected override void Act()
{
    base.Act();
    _resultEntity = Repository.Update(_itemToUpdate);
}
[TestMethod]
public void ShouldAssignEmailBeforeSave() // Act
{
   Context.AssertWasCalled(x => x.SaveChanges(), 
      options => options.WhenCalled(y => 
         Assert.IsTrue(_resultEntity.Email == "somevalue")));
}

但是我意识到"WhenCalled"方法没有执行,因为我也尝试过这个:

[TestMethod]
public void ShouldAssignEmailBeforeSave()
{
    Context.Expect(x => x.SaveChanges())
       .WhenCalled(y => Assert.IsTrue(false));
}

我也尝试过这种语法:

[TestMethod]
public void ShouldAssignEmailBeforeSave()
{
    Context.AssertWasCalled(x => x.SaveChanges(),
       options => options.WhenCalled(z => Assert.IsTrue(false)));
}

两者都断言上述传递,这很明显我没有正确使用WhenCalledContext是我的DBSet的模拟对象。我暂时把安排和法案排除在问题之外,因为他们似乎做了他们应该做的事情。是断言不起作用。

如何验证在调用方法之前是否在实体上设置了属性?换句话说,我如何断言某事以特定顺序发生?

  1. 设置属性。
  2. 保存更改。

编辑:

出现"错误"是因为断言是在法案之后完成的,这是正确的。不可能在断言中使用WhenCalled,因为该法案已经发生。在这种特殊情况下,永远不会调用 WhenCall,因为委托是在调用SaveChanges之后创建的,因此在调用时不存在。

另一种方法是在排列中使用Expect

protected override void Arrange()
{
    base.Arrange();
    _itemToUpdate = new FooEntity();
    Context.Expect(x => x.SaveChanges()).Return(0).WhenCalled(y =>
    {
        Assert.IsTrue(false);
    });
}
[TestMethod]
public void ShouldCallSaveChanges()
{
    Context.VerifyAllExpectations();
}

但是,您在安排中有一个断言,我认为这与 AAA 模式的最佳实践背道而驰。有什么更好的解决方案吗?

断言在方法调用之前已分配值

似乎您要做的是验证模拟通话的顺序。这是可能的MockRepository.Ordered() 3.5版本的方法,但不是3.6语法的一部分。
您可以在此处和此处看到可能的解决方案。对于 AAA 来说,这可能是最简单的:

Context.AssertWasCalled(x => _resultEntity.Email = "somevalue", options => options.WhenCalled(w => Context.AssertWasNotCalled(x=>x.SaveChanges())));
Context.AssertWasCalled(x=>x.SaveChanges());

我最终得到了这个:

private FooEntity _itemToUpdate;
private FooEntity _resultEntity;
protected override void Arrange()
{
    base.Arrange();
    var correctValue = "somevalue"
    _itemToUpdate = new FooEntity()
    _itemToUpdate.Email = correctValue;
    // Context is a mock of a DbContext and inherited from base class.
    Context.Expect(x => x.SaveChanges()).Return(0).WhenCalled(y =>
    {
        Assert.AreEqual(_resultEntity.Email, correctValue);
    });
    Context.Replay();
}
protected override void Act()
{
    base.Act();
    // Repository is a mock of a repository and inherited from base class.
    _resultEntity = Repository.Update(_itemToUpdate);
}
[TestMethod]
public void ShouldAssignEmailBeforeSave() // Assert
{
   Context.VerifyAllExpectations();
}

由于该实体不是模拟实体,因此 AssertWasCall 将不起作用。