正确的单元测试服务/存储库交互 [英] Correctly Unit Test Service / Repository Interaction

查看:50
本文介绍了正确的单元测试服务/存储库交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法 CreateAccount(...) 想要进行单元测试.基本上它创建一个帐户实体并将其保存到数据库中,然后返回新创建的帐户.我正在嘲笑 Repository 并期待 Insert(...) 调用.但是 Insert 方法需要一个 Account 对象.

I have a method CreateAccount(...) that I want to unit test. Basically it creates an Account Entity and saves it to the DB, then returns the newly created Account. I am mocking the Repository and expecting an Insert(...) call. But the Insert method expects an Account object.

这个测试通过了,但它似乎不正确,因为 CreateAccount 创建了一个帐户,而我正在为 Mock'ed 预期调用创建一个帐户(两个单独的帐户实例).测试这种方法的正确方法是什么?还是我使用这种方法创建帐户不正确?

This test passes, but it just does not seem correct, because CreateAccount creates an account, and I am creating an account for the Mock'ed expected call (two seperate Account instances). What would be the correct way to test this method? Or is me creating Accounts using this method incorrect?

[Fact]
    public void can_create_account()
    {
        const string email = "test@asdf.com";
        const string password = "password";
        var accounts = MockRepository.GenerateMock<IAccountRepository>();
        accounts.Expect(x => x.Insert(new Account()));
        var service = new AccountService(accounts);

        var account = service.CreateAccount(email, password, string.Empty, string.Empty, string.Empty);

        accounts.VerifyAllExpectations();
        Assert.Equal(account.EmailAddress, email);
    }

这是 CreateAccount 方法:

And here is the CreateAccount Method:

public Account CreateAccount(string email, string password, string firstname, string lastname, string phone)
    {
        var account = new Account
                          {
                              EmailAddress = email,
                              Password = password,
                              FirstName = firstname,
                              LastName = lastname,
                              Phone = phone
                          };

        accounts.Insert(account);
        return account;
    }

推荐答案

[Test]
public void can_create_account()
{
    const string email = "test@asdf.com";
    const string password = "password";

    Account newAcc = new Account();
    var accounts = MockRepository.GenerateMock<IAccountRepository>();

    var service = new AccountService(accounts);
    var account = service.CreateAccount(email, password, string.Empty, 
                                        string.Empty, string.Empty);

    accounts.AssertWasCalled(x => x.Insert(Arg<Account>
                            .Matches(y => y.EmailAddess == email 
                                       && y.Password == password)));                   

    Assert.AreEqual(email, account.EmailAddress);
    Assert.AreEqual(password, account.Password);
}

所以你在这里测试的本质上是一个工厂方法(即它创建一个对象的新实例并返回它).我所知道的测试这些方法的唯一方法是检查我们是否返回了一个具有我们期望的属性的对象(上面的最后两个 Assert.Equal 调用正在执行此操作).你在你的方法中有一个对存储库的额外调用;所以我们需要额外的 AssertWasCalled 调用和上面的属性比较(以确保对象的正确实例被用作此调用的参数).

So what you're testing here is essentially a factory method (i.e. it creates a new instance of an object and returns it). The only way that I know of testing these sorts of methods is by checking that we get returned an object with the properties that we are expecting (the last two Assert.Equal calls above are doing this). You have an additional call to a repository in your method; and so we need the additional AssertWasCalled call with the property comparison as above (to make sure that the right instance of object was used as a parameter to this call).

这篇关于正确的单元测试服务/存储库交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆