2

以下を考えると、これは MOQ の適切な使用法ですか? 私は「モッキング」、「スタブ」、「偽造」などに非常に慣れておらず、頭を包み込もうとしています。

私が理解している方法は、このモックが既知の結果を提供しているので、それを使用してこのサービスをテストすると、サービスは適切に反応しますか?

public interface IRepository<T> where T : class
{
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    IQueryable<T> Query();
}

public interface ICustomerService
{
    void CreateCustomer(Customer customer);
    Customer GetCustomerById(int id);
}

public class Customer
{
    public int Id { get; set; }

}

public class CustomerService : ICustomerService
{
    private readonly IRepository<Customer> customerRepository;

    public CustomerService(IRepository<Customer> customerRepository)
    {
        this.customerRepository = customerRepository;
    }

    public Customer GetCustomerById(int id)
    {
        return customerRepository.Query().Single(x => x.Id == id);
    }

    public void CreateCustomer(Customer customer)
    {
        var existingCustomer = customerRepository.Query().SingleOrDefault(x => x.Id == customer.Id);

        if (existingCustomer != null)
            throw new InvalidOperationException("Customer with that Id already exists.");

        customerRepository.Add(customer);
    }
}

public class CustomerServiceTests
    {
        [Fact]
        public void Test1()
        {
            //var repo = new MockCustomerRepository();
            var repo = new Mock<IRepository<Customer>>();
            repo.Setup(x => x.Query()).Returns(new List<Customer>() { new Customer() { Id = 1 }}.AsQueryable());

            var service = new CustomerService(repo.Object);

            Action a = () => service.CreateCustomer(new Customer() { Id = 1 });

            a.ShouldThrow<InvalidOperationException>();

        }
    }

xUnit、FluentAssertions、および MOQ を使用しています。

4

2 に答える 2

1

テストは私には問題ないように見えます。モックは、テストのためだけにハードコードされた回答を返す偽のリポジトリを提供するだけなので、テストはテストしているサービスだけを気にし、実際のデータベースなどは扱いません。ここではテストしていないためです。

さらに完全にするために、テストに1つだけ追加します。モックでメソッド呼び出しを設定するときは、テスト対象のシステムによって実際に呼び出されたことを確認してください。結局のところ、サービスはリポジトリに何らかのオブジェクトを要求し、特定の戻り値の下でのみスローすることになっています。特に Moq は、このための構文を提供します。

repo.VerifyAll();

これが行うことは、以前に配置したセットアップが実際に少なくとも 1 回呼び出されたことを確認するだけです。これにより、サービスがリポジトリを呼び出さずにすぐに例外をスローするエラーから保護できます (あなたのような例では簡単に見つけることができますが、複雑なコードでは呼び出しを見逃すのは簡単です)。その行で、テストの最後に、サービスがリストを要求するレポを呼び出さなかった場合 (およびその特定のパラメーターのセットを使用して)、例外が適切にスローされたとしても、テストも失敗します。

于 2013-08-17T00:51:19.643 に答える