Mock ve Moq Nedir ?

Mock ve Moq Nedir ?

Mock nedir ?

Mock yapısı uygulamamızın içerisindeki class ve interface'lerin davranışların taklit etmemizi sağlayan yapıdır.

Mock'a neden ihtiyaç duyarız ?

Örneğin : Bir api'ye uzun süren bir istek atıyoruz bu isteğimize cevap gelmesi 5 sn sürüyor diyelim. Peki biz bu api'ye 10 kere istek atarsak her defasından 5sn bekleyerek toplam 50 sn beklemiş oluruz ama biz bunu istemiyoruz. Eğer api'den gelen değeri biliyorsak bizim tek yapmamız gereken işlem bu api'ye giden isteği bir şekilde taklit ederek sonucuna da bildiğimiz sonucu yazarız. Yani mock'un faydalarından bir tanesi :

  • Zaman kazandırmasıdır.

Mock kullabilmenin şartları :

Abstraction kullanmak. => Mutlaka gereklidir mock kullanabilmek için.

DI kullanıyorsanız rahatlıkla mock'lamayı çok rahat yapabilirsiniz.

Moq nedir ?

  • Mock framework'üdür.
  • .net tarafında mock interface ve class'ların davranışını taklit etmemizi sağlayan bir framework'tür.

Moq örnek :

Github

Öncelikle yukarıdaki projeyi local'inize indirin.

Commit'leri inceleyip projeyi iyice incelerseniz davranış değişikliğinden kastın ne demek olduğunu göreceksiniz.

Bu projeyi inceledikten sonra gelelim kilit code satırlarına.

using Moq;
using SaySomething.App;
using System;
using Xunit;

namespace SaySomething.Test
{
    public class SaySomethingTest
    {
        /*Kullanımmı anlayabilmeniz için : 
         * İlk başta Normal kullanım olan yerleri comment'ten çıkartın
         * Assert metodunu da comment den çıkartın.
         * testi çalıştırın
         * ve class ile interface'lerin davranışını inceleyin.
         * 
         * 
         * Davranışı anladıktan sonra uncomment yaptığınız yerleri comment'leyip.
         * 
         * 
         * Mock ile kullanımı adlı yerleri comment'ten çıkartın.
         * Assert metodunu da comment çıkartın.
         * testi çalıştırın
         * ve class ile interface'lerin davranışını inceleyin.
         * 
         */
        private readonly SayHelloTo _sayHelloTo;
        public Mock<ISayHelloToService> mymock { get; set; }
        public SaySomethingTest()
        {

            /*Normal kullanım :
             *_sayHelloTo = new SayHelloTo(new SayHelloToService());
             */

            //Mock ile kullanımı:
            mymock = new Mock<ISayHelloToService>();
            _sayHelloTo = new SayHelloTo(mymock.Object);


        }

        [Theory]
        [InlineData("Mustafa", "Hello Mustafa")]
        [InlineData("Mehmet", "Hello Mehmet")]
        [InlineData("Ömer", "Hello Ömer")]
        public void SayHelloToMustafa(string name, string expectedValue)
        {

            /*Normal kullanım:
            *var value = _sayHelloTo.SayHello(name);
            */

            //Mock ile kullanım:
            mymock.Setup(x => x.SayHelloTo(name)).Returns("Hello " + name);
            var value = _sayHelloTo.SayHello(name);


            Assert.Equal(expectedValue, value);

        }
    }
}

aşağıdaki satırla SayHelloTo class'ındaki metotları test etmek için yazdık.

private readonly SayHelloTo _sayHelloTo;

aşağıdaki satır ile de ISayHelloToService interface'ini taklit edeceğimiz için yazdık.

public Mock<ISayHelloToService> mymock { get; set; }

aşağıdaki satır ile de intialize işlemleri yaptık. Dikkat ederseniz SayHelloTo new'lerken ona mymock ile yarattığımız taklit objemizi verdik.

mymock = new Mock<ISayHelloToService>();
_sayHelloTo = new SayHelloTo(mymock.Object);

Daha sonra test metodumuz olan SayHelloToMustafa'da : ISayHelloToService interface taklit eden mymock nesnesinin : Setup diyerek, SayHelloTo metoduna name parametres verildiğinde Return diyerek, Return parameteresindeki değeri dönmesini istedik. Yani verilen ame değeri göre "Hello " + name demesini istedik.

mymock.Setup(x => x.SayHelloTo(name)).Returns("Hello " + name);
var value = _sayHelloTo.SayHello(name);

Anlayacağınız üzere moq interface ve class'larımızın davranışını taklit etmemizi sağlar.

Daha detaylı bilgi için :

Fatih Çakıroğlu'nun udemy kursu