#mstest etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
#mstest etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

2 Eylül 2023 Cumartesi

Asp Net Core'da Moq Kütüphanesi ile Unit Test Yazımı

 

Asp Net Core'da Moq Kütüphanesi ile Unit Test Yazımı

Daha önceki yazımızda Birim Test Nedir konusuna değinmiştik ve birim test için kullanılabilecek frameworkleri vermiştik. Bu yazımızda Db operasyonları olan bir projede unit test yazmak istersek ne yapardık bu soruya cevap arıyor olacağız.

Bir UserRepository sınıfımız olsun ve bu repository için unit test metotları yazıyor olalım. Peki ama test metotlarını yazarken nasıl bir yol izleyeceğiz ? Her bir test case’i için gidip veritabanına dummy kayıtlar atıp CRUD işlemleri yapmamamız gerekir. Bu gibi durumlar için mocking dediğimiz “alaycı” veya “sahte” kayıtlar oluşturmamızı sağlayan library’ler bulunmakta. Bu library’lerden Moq’u kullanarak sahte nesneler üreterek UserRepository için basit bir test projesi yazacağız. Peki bu Moq nedir?

 

Moq Nedir ?

Mock kavramı istediğimiz bir nesnenin yerine geçebilen fake nesnelerdir. Bu objelerin istediğimiz gibi davranmalarını sağlayabiliriz. Moq’ta bu tarz işlemleri handle eden ve mock objelerini bize hazır sunan bir kütüphane.

 

Örnek Proje

Örnek projemiz için öncelikle bir tane UnitTestWithMoq adımda Console Application oluşturalım ve içerisine IUserRepository.cs arayüzünü ve User.cs sınıfını aşağıdaki gibi tanımlayalım. 


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
namespace UnitTestWithMoq
{
    public interface IUserRepository
    {
        IList<User> GetAll();
        User GetById(int userId);
        void Insert(User user);
        void Update(User user);
        void Delete(int Id);
    }
}

 

1
2
3
4
5
6
7
8
9
namespace UnitTestWithMoq
{
    public class User
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

 

Şimdi ise UnitTestWithMoq.Test adında test projemizi oluşturalım ve UnitTestWithMoq projemizi referans olarak test projemize ekleyelim. Sonrasında test projemize Nuget üzerinden Moq kütüphanesini kuralım.

Tools > Nuget Package Manager > Package Manager Console > PM> Install-Package Moq

Kurulum işlemi tamamlandıktan sonra UserRepositoryTest adında bir class oluşturalım.

İlk olarak UserRepository için gerekli olan setup işlemlerini yapalım. Setup işlemi kısaca repository’nin içerisindeki metotların sahte objelerle işlemleri yapmasını sağlayacak kodları yazmak diyebiliriz. Mocking setup ile ilgili kodlarımız aşağıdaki gibi olacaktır.

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
namespace UserRepositoryTest
{
    [TestClass]
    public class UserRepositoryTest
    {
        public readonly IUserRepository MockUserRepository;
        public UserRepositoryTest()
        {
            // Test metotları genelinde kullanacağımız User listesi
            var userList = new List<User>
            {
                new User {Id=1,FirstName="User1",LastName="User1LastName" },
                new User {Id=2,FirstName="User2",LastName="User2LastName" },
                new User {Id=3,FirstName="User3",LastName="User3LastName" }
            };
            // Mock the Products Repository using Moq
            var mockUserRepository = new Mock<IUserRepository>();
            // GetAll metodu için setup işlemi
            mockUserRepository.Setup(mr => mr.GetAll()).Returns(userList);
            // GetById metodu için setup işlemi
            mockUserRepository.Setup(mr => mr.GetById(It.IsAny<int>())).Returns((int i) => userList.Single(x => x.Id == i));
            // Insert için setup işlemi
            mockUserRepository.Setup(mr => mr.Insert(It.IsAny<User>())).Callback(
                (User target) =>
                {
                    userList.Add(target);
                });
            // Update için setup işlemi
            mockUserRepository.Setup(mr => mr.Update(It.IsAny<User>())).Callback(
                (User target) =>
                {
                    var original = userList.Where(q => q.Id == target.Id).Single();
                    if (original == null)
                    {
                        throw new InvalidOperationException();
                    }
                    original.FirstName = target.FirstName;
                    original.LastName = target.LastName;
                });
            // Test metotlarından erişilebilmesi için global olarak tanımladığımız MockUserRepository'e yukarıdaki setup işlemlerini atıyoruz
            this.MockUserRepository = mockUserRepository.Object;
        }
    }
}

 

Peki biz bu kodlarda ne yapıyoruz.

IUserRepository diye CRUD işlemlerinin yapıldığı bir class’ın ve bu class içerisinde bulunan GetAll, GetById, Insert, Update, Delete metotları için tanımlanan mocking veya kandırmaca işlemleri yukarıdaki gibidir. Database üzerinden bu işlemleri yapmak yerine rahatça userList array’i üzerinden bu işlemleri yapabilir.

 

GetAll metodunu çağırarak bize veri döndüğünü gösteren test metodu.

1
2
3
4
5
6
7
 [TestMethod]
 public void GetAll_Than_Check_Count_Test()
 {
    var expected = this.MockUserRepository.GetAll().Count;
    Assert.IsNotNull(expected); // test not null
    Assert.IsTrue(expected > 0);// test GetAll returns user objects
}

 

GetById metodu için doğru objeyi return edip etmediği durumu için test metodu.

1
2
3
4
5
6
7
8
9
[TestMethod]
public void GetById_Than_Check_Correct_Object_Test()
{
     var actual = new User { Id = 2, FirstName = "User2", LastName = "User2LastName" };
     var expected = this.MockUserRepository.GetById(2);
     Assert.IsNotNull(expected); // Test is not null
     Assert.IsInstanceOfType(expected, typeof(User)); // Test type
     Assert.AreEqual(actual.Id, expected.Id); // test correct object found
}

  

Insert işleminden sonra GetAll metodundan dönen object sayısı doğrumu testi

1
2
3
4
5
6
7
8
9
[TestMethod]
public void Insert_User_Than_Check_GetAll_Count_Test()
{
    var actual = this.MockUserRepository.GetAll().Count + 1;
    var user = new User { Id = 4, FirstName = "User4", LastName = "User4LastName" };
    this.MockUserRepository.Insert(user);
    var expected = this.MockUserRepository.GetAll().Count;
    Assert.AreEqual(actual, expected);
}

 

 GetById metoduna hatalı bir Id ile çağrım yapıldığında Exception döneceği durumu için test metodu.

1
2
3
4
5
6
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]//Eğer beklediğimiz bir exception var ise bu şekilde tanımlayabiliriz
public void GetyId_With_Undefined_Id_Than_Exception_Occurred_Test()
{
    var expected = this.MockUserRepository.GetById(It.IsAny<int>());
}

  

Update işlemi sonrasında GetById yapılarak dönen nesnede bulunan değerler doğrumu test metodu.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[TestMethod]
public void Update_User_Than_Check_It_Is_Updated_Test()
{
    var actual = new User { Id = 2, FirstName = "User2_Updated", LastName = "User2LastName_Updated" };
    this.MockUserRepository.Update(actual);
    var expected = this.MockUserRepository.GetById(actual.Id);
    Assert.IsNotNull(expected);
    Assert.AreEqual(actual.FirstName, expected.FirstName);
    Assert.AreEqual(actual.LastName, expected.LastName);
}

 

Test metotlarını yazdıktan sonra Run All Tests diyerek testlerimizi çalıştırıp success-fail durumlarını görebiliriz.

Bu yazımızda Moq kullanarak basitçe bir Unit Test projesi hazırladık. Artık yazılım dünyasında unit test olmazsa olmazdır. Umarım faydalı olmuştur.

Yararlanılan kaynaklar

Kaynak Kodu 

http://www.canertosuner.com/post/moq-kullanarak-unittest-yazma

Unit Test Nedir ? Asp.Net ve Asp.Net Core’da Unit Test

 

Unit Test Nedir ? Asp.Net ve Asp.Net Core’da Unit Test

 

Unit Test Nedir ?

Tabiki de hatasız kod olmaz. Her zaman sizden sonra gelen geliştirici, kodta ekstra hatalar bulabilir. Yada ekstra özellikler ekleyebilir. Bu yüzden birim testi yazılan bir kodun anlaşılması daha kolaydır. Sizden sonra gelen geliştiricide kodu daha hızlı bir şekilde anlayabilir.

 

DevOps Açısından Unit Test

Unit Test artık yazılım dünyasında olmazsa olmaz bir kural olarak bütün projelerde yazılması zorunlu hale gelmektedir. DevOps açısından düşündüğümüzde Continuous Integration ve Continuous Deployment araçları yazmış olduğumuz kodları derleyip edip yüklemeden önce ilk olarak birim test metotlarını çalıştırır. Bu metotlardan herhangi biri hat aldığında yüklemeyi durdurabilir. Böylelikle birim test yazmak artık yazılım geliştirme dünyasında olsa da olur olmaktan çıkıp olmalıdır haline gelmektedir.

 

Asp.Net ve Asp.Net Core’da Unit test

ASP.NET’de birim test yazmak için genellikle NUnit veya Microsoft tarafından sağlanan Visual Studio Test Runner kullanılır. Bunlar, bir sınıfın veya birim işlevinin bir parçası olarak çalışan kodların test edilmesine olanak tanır. Bunlar, kodun daha önce yazılmış testlerle uyumlu olup olmadığını ve beklenen sonuçları üretip üretmediğini doğrulamak için kullanılabilir.

ASP.NET Core’da birim test yazmak için, .NET Core 2.1 veya üstü bir sürümü ve genellikle xUnit, NUnit veya MSTest frameworklerini kullanabilirsiniz. Bu frameworkler, birim testlerinin oluşturulması, yürütülmesi ve sonuçlarının değerlendirilmesi için araçlar sağlar. ASP.NET Core, birim testlerinin yazılması ve yürütülmesi için birçok özellik ve fayda sağlar. Bu, kodun test edilmesini ve hataların tespit edilmesini kolaylaştırır.

ASP.NET ve ASP.NET Core’da birim test kullanarak, yazılımın doğru çalıştığından ve beklenen sonuçları ürettiğinden emin olabilirsiniz. Bu, yazılım geliştirme sürecinde önemli bir adımdır ve kodun güvenilirliğini arttırır. Ayrıca, birim test kullanımı, kodun daha kolay bakımının yapılmasını sağlar ve geliştirme sürecinin daha hızlı ve verimli olmasına yardımcı olur.

 

Bazı Unit Test Framework'leri

  1. NUnit: NUnit, özellikle .NET uygulamaları için tasarlanmış açık kaynaklı bir birim test kütüphanesidir. Asp.Net ve Asp.Net Core uygulamalarında da sıkça kullanılmaktadır.
  2. xUnit: xUnit, açık kaynaklı bir birim test kütüphanesidir ve .NET Core ile uyumludur. Asp.Net Core uygulamaları için özellikle uygun bir birim test kütüphanesidir.

Bu kütüphanelerden birini kullanarak kendinize uygun test metodları oluşturabilirsiniz. Bir sonraki yazımızda Moq kütüphane kullanarak Unittest projesi oluşturacağız. Umarım faydalı olmuştur.

Yararlanılan kaynaklar

http://www.canertosuner.com/post/asp-net-core-unit-test 

https://medium.com/@resulzel/unit-test-nedir-ff353aac240a 

 

 

.Net Core'da Swagger UI Kullanımı

  Web API geliştirirken API de yazılan metodların ne iş yaptığı? Hangi parametreleri aldığı? Ne cevap döndüğü? Gibi bilgilerin yer aldığı ...