데이터베이스 함수 Mock이 C # 웹 API 단위 테스트에서 작동하지 않습니다.

RJCoder

내 컨트롤러 방법은 다음과 같습니다.

[HttpPost]
    [Authorize]
    [Route(RouteConfig.Routes.LovList.contactStatus)]
    public IHttpActionResult ContactStatusList()
    {
        try
        {
            var result = new DBClass.HeroDb().GetList(
                            DBClass.DBConstants.ListConstants.query_Contact_Status);
            return Json(new Models.Response(
                        Models.ResponseMessages.Success,
                        result)
                     );
        }
        catch(System.Data.SqlClient.SqlException)
        {
            return InternalServerError();
        }
        catch(System.Exception ex)
        {
            Logger.Error(ex, ex.Message, ex.StackTrace);
            return InternalServerError();
        }
        
    }

그리고 이것은 내 테스트 케이스 방법입니다.

[TestMethod()]
    public void ContactStatusListTest()
    {
        
        Mock<DBClass.HeroDb> mock = new Mock<DBClass.HeroDb>();
        mock.Setup(x => x.GetList(DBClass.DBConstants.ListConstants.query_Contact_Status))
            .Returns(CreateContactList());
        var result = new ListController().ContactStatusList();
        Models.Response response = (Models.Response)result;
        Assert.AreEqual(response.Message, Models.ResponseMessages.Success);
        Assert.IsNotNull(response.Data);
    }
    public System.Data.DataTable CreateContactList()
    {
        DataTable table = new DataTable();
        table.Columns.Add("ContactStatus");
        DataRow row1 = table.NewRow();row1["ContactStatus"] = "Contacted"; table.Rows.Add(row1);
        DataRow row2 = table.NewRow(); row2["ContactStatus"] = "Not Contacted"; table.Rows.Add(row2);
        DataRow row3 = table.NewRow(); row3["ContactStatus"] = "Contacted"; table.Rows.Add(row3);
        return table;
    }

내 테스트 메서드에서 GetList () 함수 를 조롱하려고했지만 작동하지 않습니다. 컨트롤러 메서드에서 내부 서버 오류가 발생합니다. Conrol은

var result = new DBClass.HeroDb()
            .GetList(DBClass.DBConstants.ListConstants.query_Contact_Status);

이 줄과 db 개체는 여기서 null입니다. 나는 단위 테스트 케이스 구축의 초보자이므로 도와주세요.

제롬 MEVEL

우선 기초를 먼저 설정해 보겠습니다. 단위 테스트는 통합 테스트와 다릅니다 .

이 경우 컨트롤러의 메서드에 대한 단위 테스트입니다ContactStatusList . 이 방법 만 테스트하고 있으며 실제로 HeroDb개체 를 조롱하여 작업을 올바르게 수행했습니다 . 이 개체 는 종속성 이므로 모의로 결정했습니다 .

문제는 당신이 모의을 설정하지만에 있기 때문에 당신이 그것을 사용하지 않는 것입니다 ContactStatusList방법은 전화 new DBClass.HeroDb().

두 번째 문제는 수업을 모의하려고한다는 것입니다. 이것은 실제로 가능하지만 모의하려는 모든 클래스의 메서드는 가상으로 선언되어야합니다. 따라서 실제로 인터페이스를 조롱하는 것이 좋습니다.

이 인터페이스는 ListController. 웹 프로젝트를 정기적으로 실행할 때 시작시 해당 인터페이스의 인스턴스를 삽입하지만 단위 테스트에서는 ListController의 생성자에 모의를 제공합니다 .

이 규칙을 기억하십시오. 모든 종속성은 컨트롤러의 생성자에 의해 수신되어야합니다.

다음은 인터페이스와 DbHero 클래스입니다.

public interface IDbHero
{
    IEnumerable<Contact> GetList(QueryContactStatus status);
}

public class DbHero : IDbHero
{
    public IEnumerable<Contact> GetList(QueryContactStatus status)
    {
        // Implementation here
    }
}

이제 컨트롤러가 있습니다.

[ApiController]
[Route("api/[controller]")]
public class ListController: ControllerBase
{
    private readonly IHeroDb _heroDb;

    public ListController(IHeroDb heroDb)
    {
        _heroDb = heroDb ?? throw new ArgumentNullException(nameof(heroDb));
    }
    
    [HttpPost]
    [Authorize]
    [Route(RouteConfig.Routes.LovList.contactStatus)]
    public IHttpActionResult ContactStatusList()
    {
        try
        {
            var result = _heroDb.GetList(DBClass.DBConstants.ListConstants.query_Contact_Status);
            return Json(new Models.Response(
                        Models.ResponseMessages.Success,
                        result)
                     );
        }
        catch(System.Exception ex)
        {
            Logger.Error(ex, ex.Message, ex.StackTrace);
            throw;
        }
    }
}

SqlException처리되지 않은 예외가있는 경우 서버가 내부 서버 오류를 반환하므로 오류를 기록하지 않으면 잡는 것이 쓸모가 없기 때문에 어쨌든 잡는 블록 만 제거 했습니다. 또한 두 번째 catch 블록 throw에서 서버가 자동으로 내부 서버 오류를 반환합니다. 디버그 모드에있는 경우 전체 예외가 반환되므로 유용 할 수 있지만 반환 InternalServerError()하면 디버그에서도 정보를 얻지 못하며 로그를 확인해야합니다.

클래스 ConfigureServices메소드 Startup.cs에서 IDbHero인터페이스 구현을 삽입하십시오 . 이는 범위지정된 서비스이므로 각 HTTP 요청에 대해 새 인스턴스가 생성됩니다. 개인적으로 데이터베이스 액세스 레이어를 싱글 톤 으로 삽입하지 않습니다 .이 레이어가 구현되는 방식에 따라 몇 가지 문제가 발생할 수 있기 때문입니다. 예를 들어 EF Core의 DbContext싱글 톤 패턴 과 호환되지 않습니다 .

services.AddScoped<IDbHero>(_ => new DBClass.HeroDb(Configuration.GetConnectionString("DbHeroConnectionString")));

코드 예제에 연결 문자열에 대한 언급이 없기 때문에 데이터베이스와의 연결을 어떻게 처리하는지 모르겠지만 위와 같은 작업을 수행합니다.

연결 문자열은 appsettings.json구성 파일 에서 가져옵니다.

"ConnectionStrings": {
    "DbHeroConnectionString": "YourConnectionString"
  }

이제 단위 테스트에서 모의 ​​객체를 사용하려면 다음과 같이하십시오.

[TestMethod()]
public void ContactStatusList_ShouldReturnData_WhenCalled()
{
    // ARRANGE
    var mock = new Mock<IHeroDb>();
    mock.Setup(x => x.GetList(DBClass.DBConstants.ListConstants.query_Contact_Status))
        .Returns(CreateContactList());
    
    var sut = new ListController(mock.Object);
        
    // ACT
    var result = sut.ContactStatusList();
    
    // ASSERT
    Models.Response response = (Models.Response)result;
    Assert.AreEqual(response.Message, Models.ResponseMessages.Success);
    Assert.IsNotNull(response.Data);
}

여기에서 몇 가지 사항에 주목하십시오.

  • 단위 테스트 이름 : 다음 3 가지가 표시되어야합니다.

    • 테스트 대상 (방법)
    • 결과는 무엇입니까 (데이터가있는 결과, 오류가있는 결과, 예외 발생 등)
    • 이 결과가 발생해야하는 조건

    매개 변수에 잘못된 값이있을 때 메서드가 오류를 반환하는지 예를 들어 테스트 할 수 있습니다. 다른 단위 테스트에서 테스트해야합니다.

  • 단위 테스트는 3 개 부분으로 항상 ARRANGE, ACT하고 ASSERT. 코드를 더 잘 구성 할 수 있도록 각 테스트에서 작성하는 것이 항상 좋은 방법입니다.

  • sut의미 System Under Test: 이것은 당신이 테스트하고 싶은 DbHero것이고 , 다른 모든 의존성 (당신의 레이어 와 같은 )은 모의 되어야합니다.

이제 다음 단계는 단위 테스트를 작성하여 DbHero.GetList. 이번에 DbHero는 테스트하려는 것이기 때문에 클래스 의 실제 인스턴스 (모의가 아님)를 만들 것입니다 . 이것이 바로 sut 입니다.

저는 테스트에서 중급 수준이므로 제가 보여 드리는 것은 동료들로부터 배운 모범 사례입니다. 그러나 더 많은 경험 개발자가 저보다 더 나은 방법을 제시 할 수 있습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

데이터베이스에 대한 PHP 웹 사이트 양식이 작동하지 않습니다.

분류에서Dev

스트라이프 웹훅에 대한 firebase 함수가 async-await에서 작동하지 않습니다.

분류에서Dev

데이터베이스의 Sqlite3 삽입 데이터가 C에서 작동하지 않습니다.

분류에서Dev

데이터베이스에 데이터를 생성하지 않고 데이터베이스와 상호 작용하는 단위 테스트 코드

분류에서Dev

다른 데이터베이스 필드를받을 수있는 동안 데이터베이스에서 ID 수신이 작동하지 않습니다.

분류에서Dev

Implode 함수는 데이터베이스 테이블에 데이터를 저장하지 않습니다.

분류에서Dev

단위 테스트에서 잠금이 작동하지 않음

분류에서Dev

웹 페이지에 데이터베이스의 다른 데이터를 표시 할 수 없습니다.

분류에서Dev

데이터베이스 연결이 작동하지 않음 C #

분류에서Dev

Azure 데이터베이스에 연결하는 Azure 웹 사이트는 로컬에서 제대로 작동하지만 배포되지는 않습니다.

분류에서Dev

단위 테스트 케이스 MockRestServiceServer 예상 URL이 RestTemplate에서 작동하지 않습니다.

분류에서Dev

단위 테스트간에 변수를 사용하는 방법은 무엇입니까? C # 웹 드라이버

분류에서Dev

Altervista 웹 사이트의 PHP 데이터베이스에서 작동하지 않는 등록

분류에서Dev

이메일 확인. 웹 사이트에서 액세스 할 때 작동하지만 단위 테스트에 실패합니다.

분류에서Dev

Firebase 데이터베이스가 작동하지 않습니다.

분류에서Dev

Python 웹 서버 스크립트가 sqlite3 데이터베이스에 제출되지 않습니다.

분류에서Dev

Python 웹 서버 스크립트가 sqlite3 데이터베이스에 제출되지 않습니다.

분류에서Dev

엔티티 프레임 워크 C # 웹 API를 사용하여 내 데이터베이스에 연결하는 데 문제가 있습니다.

분류에서Dev

django-localeurl 패치 된 역방향이 단위 테스트에서 작동하지 않습니다.

분류에서Dev

데이터베이스 테이블이 c #을 업데이트하지 않습니다.

분류에서Dev

Objective C SQLite 삽입 문이 작동하지 않음 데이터베이스가 잠겨 있습니다.

분류에서Dev

작동하지 않는 두 날짜 사이의 총 수익 C # ms 액세스 데이터베이스

분류에서Dev

단일 웹 페이지에서 데이터베이스 레코드 이동

분류에서Dev

Django 단위 테스트 client.login이 작동하지 않습니다.

분류에서Dev

특정 웹 사이트에서 스크랩이 작동하지 않습니다.

분류에서Dev

내 웹 사이트에서 jquery 스크롤이 작동하지 않습니다.

분류에서Dev

데이터베이스에서 데이터를 가져 오기 위해 웹 서비스를 호출하기 위해 매개 변수에 데이터베이스 사용자와 비밀번호를 전달해야합니까?

분류에서Dev

데이터베이스의 테이블에서 수량을 확인한 후 Insert SQL 문이 작동하지 않습니다.

분류에서Dev

C # 단위 테스트에서 예외를 throw하지 않는 모의 함수

Related 관련 기사

  1. 1

    데이터베이스에 대한 PHP 웹 사이트 양식이 작동하지 않습니다.

  2. 2

    스트라이프 웹훅에 대한 firebase 함수가 async-await에서 작동하지 않습니다.

  3. 3

    데이터베이스의 Sqlite3 삽입 데이터가 C에서 작동하지 않습니다.

  4. 4

    데이터베이스에 데이터를 생성하지 않고 데이터베이스와 상호 작용하는 단위 테스트 코드

  5. 5

    다른 데이터베이스 필드를받을 수있는 동안 데이터베이스에서 ID 수신이 작동하지 않습니다.

  6. 6

    Implode 함수는 데이터베이스 테이블에 데이터를 저장하지 않습니다.

  7. 7

    단위 테스트에서 잠금이 작동하지 않음

  8. 8

    웹 페이지에 데이터베이스의 다른 데이터를 표시 할 수 없습니다.

  9. 9

    데이터베이스 연결이 작동하지 않음 C #

  10. 10

    Azure 데이터베이스에 연결하는 Azure 웹 사이트는 로컬에서 제대로 작동하지만 배포되지는 않습니다.

  11. 11

    단위 테스트 케이스 MockRestServiceServer 예상 URL이 RestTemplate에서 작동하지 않습니다.

  12. 12

    단위 테스트간에 변수를 사용하는 방법은 무엇입니까? C # 웹 드라이버

  13. 13

    Altervista 웹 사이트의 PHP 데이터베이스에서 작동하지 않는 등록

  14. 14

    이메일 확인. 웹 사이트에서 액세스 할 때 작동하지만 단위 테스트에 실패합니다.

  15. 15

    Firebase 데이터베이스가 작동하지 않습니다.

  16. 16

    Python 웹 서버 스크립트가 sqlite3 데이터베이스에 제출되지 않습니다.

  17. 17

    Python 웹 서버 스크립트가 sqlite3 데이터베이스에 제출되지 않습니다.

  18. 18

    엔티티 프레임 워크 C # 웹 API를 사용하여 내 데이터베이스에 연결하는 데 문제가 있습니다.

  19. 19

    django-localeurl 패치 된 역방향이 단위 테스트에서 작동하지 않습니다.

  20. 20

    데이터베이스 테이블이 c #을 업데이트하지 않습니다.

  21. 21

    Objective C SQLite 삽입 문이 작동하지 않음 데이터베이스가 잠겨 있습니다.

  22. 22

    작동하지 않는 두 날짜 사이의 총 수익 C # ms 액세스 데이터베이스

  23. 23

    단일 웹 페이지에서 데이터베이스 레코드 이동

  24. 24

    Django 단위 테스트 client.login이 작동하지 않습니다.

  25. 25

    특정 웹 사이트에서 스크랩이 작동하지 않습니다.

  26. 26

    내 웹 사이트에서 jquery 스크롤이 작동하지 않습니다.

  27. 27

    데이터베이스에서 데이터를 가져 오기 위해 웹 서비스를 호출하기 위해 매개 변수에 데이터베이스 사용자와 비밀번호를 전달해야합니까?

  28. 28

    데이터베이스의 테이블에서 수량을 확인한 후 Insert SQL 문이 작동하지 않습니다.

  29. 29

    C # 단위 테스트에서 예외를 throw하지 않는 모의 함수

뜨겁다태그

보관