Correctly Unit Test Service / Repository Interaction

感情迁移 提交于 2019-12-11 18:29:26

问题


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.

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

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

回答1:


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

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).



来源:https://stackoverflow.com/questions/1080140/correctly-unit-test-service-repository-interaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!