문제

그래서 구글 테스팅 블로그를 읽다가 전역 상태가 나쁘고 테스트 작성을 어렵게 만든다고 하더군요.나는 믿습니다. 내 코드는 지금 테스트하기 어렵습니다.그렇다면 전역 상태를 어떻게 피할 수 있나요?

제가 이해하는 대로 글로벌 상태를 사용하는 가장 큰 목적은 개발, 수용 및 생산 환경 간의 주요 정보를 관리하는 것입니다.예를 들어, "DBConnectionstring"이라는 정적 멤버가있는 "Globals"라는 정적 클래스가 있습니다. 응용 프로그램이로드되면로드 할 연결 문자열이 결정되고 Globals.dbConnectionstring을 채 웁니다.Globals 클래스에 파일 경로, 서버 이름 및 기타 정보를 로드합니다.

내 기능 중 일부는 전역 변수에 의존합니다.따라서 기능을 테스트할 때 특정 전역 변수를 먼저 설정해야 한다는 점을 기억해야 합니다. 그렇지 않으면 테스트가 실패합니다.나는 이것을 피하고 싶습니다.

상태 정보를 효과적으로 관리할 수 있는 방법이 있나요?(아니면 전역 상태를 잘못 이해하고 있는 걸까요?)

도움이 되었습니까?

해결책

의존성 주입이 당신이 찾고 있는 것입니다.해당 함수를 나가서 종속성을 찾는 대신 함수에 종속성을 주입하십시오.즉, 함수를 호출하면 원하는 데이터가 함수에 전달됩니다.이렇게 하면 적절한 곳에 모의 개체를 간단히 삽입할 수 있으므로 클래스 주위에 테스트 프레임워크를 배치하는 것이 쉽습니다.

일부 전역 상태를 피하는 것은 어렵지만 이를 수행하는 가장 좋은 방법은 애플리케이션의 최고 수준에서 팩토리 클래스를 사용하는 것이며, 최상위 수준 아래의 모든 항목은 종속성 주입을 기반으로 합니다.

두 가지 주요 이점:첫째, 테스트가 훨씬 더 쉽고, 둘째, 애플리케이션이 훨씬 더 느슨하게 결합됩니다.구현보다는 클래스의 인터페이스에 대해 프로그래밍할 수 있는 능력에 의존합니다.

다른 팁

테스트에 데이터베이스나 파일 시스템과 같은 실제 리소스가 포함되는 경우 수행 중인 작업은 다음과 같습니다. 통합 테스트 오히려 단위 테스트.통합 테스트에는 몇 가지 예비 설정이 필요한 반면, 단위 테스트는 독립적으로 실행될 수 있어야 합니다.

Castle Windsor와 같은 종속성 주입 프레임워크의 사용을 살펴볼 수 있지만 간단한 경우에는 다음과 같은 중간 접근 방식을 취할 수 있습니다.

public interface ISettingsProvider
{
    string ConnectionString { get; }
}

public class TestSettings : ISettingsProvider
{        
    public string ConnectionString { get { return "testdatabase"; } };
}

public class DataStuff
{
    private ISettingsProvider settings;

    public DataStuff(ISettingsProvider settings)
    {
        this.settings = settings;
    }

    public void DoSomething()
    {
        // use settings.ConnectionString
    }
}

실제로는 구현 시 구성 파일에서 읽을 가능성이 높습니다.원한다면 교체 가능한 구성을 갖춘 완전한 DI 프레임워크를 사용하는 것이 좋습니다. 하지만 적어도 Globals.ConnectionString을 사용하는 것보다는 낫다고 생각합니다.

좋은 첫 번째 질문입니다.

짧은 대답:애플리케이션이 모든 입력(암시적 입력 포함)에서 출력까지의 함수인지 확인하세요.

설명하는 문제는 전역 상태처럼 보이지 않습니다.적어도 변경 가능한 상태는 아닙니다.오히려 당신이 설명하는 내용은 종종 "구성 문제"라고 불리는 것과 비슷해 보이며 여기에는 여러 가지 해결책이 있습니다.Java를 사용하는 경우 다음과 같은 경량 주입 프레임워크를 살펴볼 수 있습니다. 기이스.Scala에서는 일반적으로 다음과 같이 해결됩니다. 암시적.일부 언어에서는 런타임에 프로그램을 구성하기 위해 다른 프로그램을 로드할 수 있습니다.이것이 우리가 Smalltalk로 작성된 서버를 구성하는 데 사용한 방법이며, 구성 파일이 또 다른 Haskell 프로그램인 Xmonad라는 Haskell로 작성된 창 관리자를 사용합니다.

MVC 설정에서 종속성 주입의 예는 다음과 같습니다.

index.php

$container = new Container();
include_file('container.php');

컨테이너.php

container.add("database.driver", "mysql");
container.add("database.name","app");

...

$container.add(new Database($container->get('database.driver', "database.name")), 'database');
$container.add(new Dao($container->get('database')), 'dao');
$container.add(new Service($container->get('dao')));
$container.add(new Controller($container->get('service')), 'controller');

$container.add(new FrontController(),'frontController');

index.php는 여기서 계속됩니다:

$frontController = $container->get('frontController');
$controllerClass = $frontController->getController($_SERVER['request_uri']);
$controllerAction = $frontController->getAction($_SERVER['request_uri']);
$controller = $container->get('controller');
$controller->$action();

그리고 컨트롤러는 데이터베이스 드라이버, 이름 등에 따라 데이터베이스 객체에 따라 달라지는 DAO (Data Access Object) 객체에 따라 서비스 계층 객체에 따라 다릅니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top