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

时间:2016-01-26 10:14:38

标签: c# unit-testing rhino-mocks arrange-act-assert

我正在使用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. 的SaveChanges。
  3. 修改

    发生“错误”是因为Assert在Act之后完成,这是正确的。由于法案已经发生,因此无法在断言中使用WhenCalled。在这种特殊情况下,永远不会调用WhenCalled,因为在调用SaveChanges之后创建了委托,因此在调用时不存在。

    另一种方法是在Arrange:

    中使用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模式的最佳实践。是否有更好的解决方案?

2 个答案:

答案 0 :(得分:0)

您正在寻找的是验证模拟调用的顺序。这可能是版本3.5的MockRepository.Ordered()方法,但不是3.6语法的一部分 您可以看到herehere可能的解决方案。对于AAA来说,这可能是最简单的:

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

答案 1 :(得分:0)

我最终得到了这个:

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();
}

由于该实体不是模拟AssertWasCalled不能工作。