39

我有几次这样的事情会有所帮助。例如,我有一个AccountCreator带有. 我有一个最终将用于创建帐户的帐户。我将首先将属性从to映射到,然后将其传递到 repo 以最终创建它。我的测试看起来像这样:CreateNewAccountAccountCreatorIRepositoryAccountCreatorNewAccountAccountAccount

public class when_creating_an_account
{
    static Mock<IRepository> _mockedRepository;
    static AccountCreator _accountCreator;
    static NewAccount _newAccount;
    static Account _result;
    static Account _account;

    Establish context = () =>
        {
            _mockedRepository = new Mock<IRepository>();
            _accountCreator = new AccountCreator(_mockedRepository.Object);

            _newAccount = new NewAccount();
            _account = new Account();

            _mockedRepository
                .Setup(x => x.Create(Moq.It.IsAny<Account>()))
                .Returns(_account);
        };

    Because of = () => _result = _accountCreator.Create(_newAccount);

    It should_create_the_account_in_the_repository = () => _result.ShouldEqual(_account);
}

所以,我需要的是替换的东西It.IsAny<Account>,因为这并不能帮助我验证是否创建了正确的帐户。令人惊奇的是……

public class when_creating_an_account
{
    static Mock<IRepository> _mockedRepository;
    static AccountCreator _accountCreator;
    static NewAccount _newAccount;
    static Account _result;
    static Account _account;

    Establish context = () =>
        {
            _mockedRepository = new Mock<IRepository>();
            _accountCreator = new AccountCreator(_mockedRepository.Object);

            _newAccount = new NewAccount
                {
                    //full of populated properties
                };
            _account = new Account
                {
                    //matching properties to verify correct mapping
                };

            _mockedRepository
                .Setup(x => x.Create(Moq.It.IsLike<Account>(_account)))
                .Returns(_account);
        };

    Because of = () => _result = _accountCreator.Create(_newAccount);

    It should_create_the_account_in_the_repository = () => _result.ShouldEqual(_account);
}

请注意,我更改It.IsAny<>It.IsLike<>并传入了一个填充Account对象。理想情况下,在后台,一些东西会比较属性值,如果它们都匹配则让它通过。

那么,它已经存在了吗?或者这可能是您以前做过的事情并且不介意共享代码?

4

4 回答 4

46

要存根存储库以根据类似条件返回特定值,以下应该有效:

_repositoryStub
    .Setup(x => x.Create(
        Moq.It.Is<Account>(a => _maskAccount.ToExpectedObject().Equals(a))))
    .Returns(_account);
于 2012-07-05T19:43:58.953 回答
19

以下内容应该适合您:

Moq.It.Is<Account>(a=>a.Property1 == _account.Property1)

但是,正如前面提到的,您必须实施匹配标准。

于 2012-07-03T05:32:09.277 回答
0

我找不到任何与问题中描述的完全一致的东西。同时,我能找到的处理作为参数传递给模拟方法的对象的验证的最佳方法(没有引用平等的奢侈)是结合Callback预期对象模式来比较实际对象和预期对象:

public class when_creating_an_account
{
    static Mock<IRepository> _mockedRepository;
    static AccountCreator _accountCreator;
    static NewAccount _newAccount;
    static Account _result;
    static Account _expectedAccount;
    static Account _actualAccount;

    Establish context = () =>
        {
            _mockedRepository = new Mock<IRepository>();
            _accountCreator = new AccountCreator(_mockedRepository.Object);

            _newAccount = new NewAccount
                {
                    //full of populated properties
                };
            _expectedAccount = new Account
                {
                    //matching properties to verify correct mapping
                };

            _mockedRepository
                .Setup(x => x.Create(Moq.It.IsAny<Account>(_account)))
                //here, we capture the actual account passed in.
                .Callback<Account>(x=> _actualAccount = x) 
                .Returns(_account);
        };

    Because of = () => _result = _accountCreator.Create(_newAccount);

    It should_create_the_account_in_the_repository = 
        () => _result.ShouldEqual(_account);

    It should_create_the_expected_account = 
        () => _expectedAccount.ToExpectedObject().ShouldEqual(_actualAccount);
}

预期的对象模式很棒,但是在 C# 中实现起来很复杂,所以我使用了一个库来为我处理所有这些。https://github.com/derekgreer/expectedObjects

我最后一次观察查看传入的实际帐户中的属性,并将每个属性与我的“预期对象”上的相同属性进行比较。这样我就没有大量的模拟属性检查列表,也没有大量的测试观察结果。

于 2012-07-05T17:46:44.410 回答
0

如果我使用JSONConvert.SerializeObject将预期对象和实际对象转换为 JSON 字符串,然后equals在它们之间进行操作,它似乎确实会产生可接受的结果。我的想法是,如果对象的字符串表示匹配,那么它们的公共属性很可能也是相同的。

于 2020-05-07T15:20:17.513 回答