Programing

모의 프레임 워크 대 MS Fakes 프레임 워크

lottogame 2020. 8. 31. 08:18
반응형

모의 프레임 워크 대 MS Fakes 프레임 워크


NMock과 VS 2011 Fakes Framework와 같은 Mock 프레임 워크의 차이점에 대해 약간 혼란스러워합니다. MSDN을 살펴보면 Fakes를 사용하면 RhinoMock 또는 NMock처럼 종속성을 모의 할 수 있지만 접근 방식은 다르지만 Fakes는이 기능을 구현하는 코드를 생성하지만 Mocks 프레임 워크는 그렇지 않습니다. 내 이해가 맞습니까? 가짜는 또 다른 모의 프레임 워크 일뿐


귀하의 질문은 MS Fakes 프레임 워크가 NMock과 어떻게 다른지에 관한 것이었고 다른 답변이 그 중 일부를 해결 한 것으로 보이지만 여기에 그들이 어떻게 동일하고 어떻게 다른지에 대한 추가 정보가 있습니다. NMock은 RhinoMocks 및 Moq 와도 유사하므로 NMock과 함께 그룹화합니다.

NMock / RhinoMocks / Moq와 MS Fakes Framework 사이에는 3 가지 주요 차이점이 있습니다.

  • MS fakes 프레임 워크는 제네릭 형식 대신 이전 버전의 Visual Studio의 접근 자처럼 생성 된 코드를 사용합니다. 종속성에 대해 가짜 프레임 워크를 사용하려는 경우 종속성이 포함 된 어셈블리를 테스트 프로젝트의 참조에 추가 한 다음 마우스 오른쪽 단추를 클릭하여 테스트 double (스텁 또는 shim)을 생성합니다. 그런 다음 테스트 할 때 실제로 생성 된 클래스를 대신 사용합니다. NMock은 제네릭을 사용하여 동일한 작업을 수행합니다 (예 :) IStudentRepository studentRepository = mocks.NewMock<IStudentRepository>(). 제 생각에는 MS Fakes 프레임 워크 접근 방식은 실제 인터페이스가 아닌 생성 된 클래스에 대해 실제로 작업하기 때문에 테스트 내에서 코드 탐색 및 리팩토링을 금지합니다.

  • MS fakes 프레임 워크는 스텁과 두더지 (심)를 제공하는 반면 NMock, RhinoMocks 및 Moq는 모두 스텁과 모의를 제공합니다 . 나는 모의를 포함하지 않기로 한 MS의 결정을 정말로 이해하지 못하며 개인적으로 아래에 설명 된 이유로 두더지의 팬이 아닙니다.

  • MS fakes 프레임 워크를 사용하면 스텁 할 메서드의 대체 구현을 제공합니다. 이러한 대체 구현 내에서 반환 값을 지정하고 메서드 호출 방법 또는 여부에 대한 정보를 추적 할 수 있습니다. NMock, RhinoMocks 및 Moq를 사용하여 모의 객체를 생성 한 다음 해당 객체를 사용하여 스텁 반환 값을 지정하거나 상호 작용 (메소드 호출 여부 및 방법)을 추적합니다. 나는 MS 가짜 접근 방식이 더 복잡하고 덜 표현 적이라는 것을 알았습니다.

프레임 워크가 제공하는 것의 차이점을 명확히하기 위해 NMock, RhinoMocks 및 Moq는 모두 두 가지 유형의 테스트 복식 (스텁 및 모의)을 제공합니다. 가짜 프레임 워크는 스텁과 두더지 (심이라고 부름)를 제공하며 안타깝게도 모의는 포함하지 않습니다. NMock과 MS Fakes의 차이점과 유사점을 이해하려면 이러한 다양한 유형의 테스트 복식이 무엇인지 이해하는 것이 좋습니다.

스텁 : 스텁은 테스트중인 메소드에 의해 두 배가되는 테스트 요청을받을 메소드 또는 속성에 대한 값을 제공해야 할 때 사용됩니다. 예를 들어, 테스트중인 메서드가 IStudentRepository 테스트 double의 DoesStudentExist () 메서드를 호출 할 때 true를 반환하고 싶습니다.

NMock과 MS 가짜의 스텁 아이디어는 동일하지만 NMock을 사용하면 다음과 같이 할 수 있습니다.

Stub.On(mockStudentRepository).Method("DoesStudentExist").Will(Return.Value(true));

그리고 MSFakes를 사용하면 다음과 같이 할 수 있습니다.

IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository() // Generated by Fakes.
{
    DoesStudentExistInt32 = (studentId) => { return new Student(); }
};

MS Fakes 예제에서 DoesStudentExist 메서드에 대한 완전히 새로운 구현을 만듭니다 (Fakes 프레임 워크가 스텁 개체를 생성 할 때 메서드 이름에 매개 변수 데이터 형식을 추가하기 때문에 DoesStudentExistInt32라고합니다. 테스트). 솔직히 말해서 NMock 구현은 메서드 이름을 식별하기 위해 문자열을 사용하기 때문에 저를 괴롭 힙니다. (NMock이 어떻게 사용되는지 잘못 이해했다면 용서 해주세요.)이 접근 방식은 실제로 리팩토링을 방해하므로 이러한 이유로 NMock보다 RhinoMocks 또는 Moq를 적극 권장합니다.

모의 : 모의는 테스트중인 메서드와 종속성 간의 상호 작용을 확인하는 데 사용됩니다. NMock을 사용하면 다음과 유사한 기대치를 설정하여이를 수행합니다.

Expect.Once.On(mockStudentRepository).Method("Find").With(123);

이것이 제가 NMock보다 RhinoMocks와 Moq를 선호하는 또 다른 이유입니다. NMock은 이전의 기대 스타일을 사용하는 반면 RhinoMocks와 Moq는 모두 다음과 같이 테스트가 끝날 때 예상되는 상호 작용을 어설 션으로 지정하는 Arrange / Act / Assert 접근 방식을 지원합니다. :

stubStudentRepository.AssertWasCalled( x => x.Find(123));

다시 말하지만, RhinoMocks는 메서드를 식별하기 위해 문자열 대신 람다를 사용합니다. ms fakes 프레임 워크는 모의를 전혀 제공하지 않습니다. 이는 스텁 아웃 구현 (위의 스텁 설명 참조)에서 나중에 올바르게 설정되었는지 확인할 변수를 설정해야 함을 의미합니다. 다음과 같이 보일 것입니다.

bool wasFindCalled = false;

IStudentRepository studentRepository = new DataAccess.Fakes.StubIStudentRepository() 
{
    DoesStudentExistInt32 = (studentId) => 
        { 
            wasFindCalled = true;
            return new Student(); 
        }
};

classUnderTest.MethodUnderTest();

Assert.IsTrue(wasFindCalled);

스텁에서 호출을 추적 한 다음 나중에 테스트에서 주장해야하기 때문에이 접근 방식이 약간 복잡하다는 것을 알았습니다. NMock, 특히 RhinoMocks 예제가 더 표현력이 있다는 것을 알았습니다.

Moles (Shims): To be frank, I do not like moles, because of their potential for misuse. One of the things I like so much about unit testing (and TDD in particular) is that testing your code helps you to understand where you have written poor code. This is because testing poorly written code is difficult. This is not true when using moles because moles are actually designed to allow you to test against dependencies that are not injected or to test private methods. They work similarly to stubs, except that you use a ShimsContext like this:

using (ShimsContext.Create())
{
    System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(fixedYear, 1, 1); };
}

My worry with shims is that people will start seeing them as "an easier way to unit test" because it doesn't force you to write code the way you should. For a more complete write-up on this concept see this post of mine:

For more information on some concerns related to the fakes frameworks take a look at these posts:

If you're interested in learning RhinoMocks here's a Pluralsight training video (full disclosure - I wrote this course and get paid royalties for views, but I think it applies to this discussion so I'm including it here):


You are correct, but there's more to the story. The most important things to take away from this answer are:

  1. Your architecture should make proper use of stubs and dependency injection, rather than relying on the crutch of Fakes and mocks

  2. Fakes and mocks are useful for testing code you shouldn't or can't change, such as:

    • Legacy code that does not make use (or efficient use) of stubs
    • 3rd party APIs
    • Resources for which you have no source code

Shims (known as "Moles", during development) is indeed a mocking framework that operates by way of detouring calls. Instead of painstakingly building a mock (yes, even using Moq is relatively painful!), shims simply use the production code object already in place. Shims simply re-route the call from the production target to the test delegate.

Stubs are generated from interfaces in the target project. The Stub object is just that -- an implementation of the interface. The benefit to using the Stub type is that you can quickly generate a stub without cluttering up your test project with many one-time use stubs, not to mention wasting time creating them. Of course, you should still create concrete stubs, for use across many tests.

Efficiently implementing Fakes (Shims, Mocks and Stub types) takes a little getting used to, but is well worth the effort. I have personally saved weeks of development time, through use of the Shims/Mole, Mocks, and Stub types. I hope you have as much fun with the technology as I have!


As I understand it, the Visual Studio team wanted to avoid competing with the various mock libraries available for .NET. MS often faces hard decisions like this. They are dammed if they don't provide certain functionality ("why doesn't MS provide us with a mock library; mocks are such a common requirement?") and damned if they do ("why is Microsoft acting so aggressively and driving its natural supporters out of the market?") Very often, but not always, they decide to hold back from simply providing their own alternative to available and well-received technologies. That seems to be the case here.

The shim feature of Fakes is really, really useful. Sure, there are dangers. It takes some discipline to ensure you only use this where necessary. However, it fills a big gap. My main complaint is that it is only delivered with the Ultimate edition of VS 2012 and therefore will only be available to a subsection of the .NET development community. What a pity.


Fakes includes two different kinds of "fake" object. The first, called a "stub", is essentially an auto-generated dummy whose default behaviour can (and usually would) be overridden to make it a more interesting mock. It does, however, lack some of the features that most of the currently available mocking frameworks offer. For example, if you want to check that a method on a stub instance was invoked, you would need to add the logic for this yourself. Basically, if you're authoring your own mocks manually now, stubs would probably seem like an improvement. However, if you're already using a more full-featured mocking framework, you might feel like there are some important pieces missing from Fakes stubs.

The other category of object offered by Fakes, called a "shim", exposes a mechanism for replacing behaviour of dependencies that have not been (or cannot be) decoupled adequately for standard replacement via mocks. AFAIK, TypeMock is the only one of the major mocking frameworks that currently offers this sort of functionality.

BTW, if you have tried out Moles before, Fakes is essentially the same thing, finally making its way out of Microsoft Research and into an actual product.


Regarding Fake (Shim + Stub) objects, it has been well defined above, though I guess the last paragraph in the last comment summarizes the whole situation pretty well.

Though a lot of people will argue that Fake (Shim + Stub) objects are good assets to have in some unit testing cases, the downside is that no matter if you're using Visual Studio 2012 or Visual Studio 2013, these options are ONLY available with Premium or Ultimate versions. IOW, this means that you WILL NOT be to run ANY of those Fakes (Shim + Stub) on any Pro version.

You may probably see the Fakes (Shim + Stub) menu option on Pro versions, but beware, there are some pretty strong chances that you will end up with absolutely nothing... It won't generate any compilation error telling you that something important is missing, options are just not there, so don't waste your time...

It's an important factor to consider in a dev team, especially if one is the only one using Ultimate version while everybody else uses Pro version... Moq on the other hand can easily be installed through Nuget no matter which Visual Studio version you use. I had no problem using Moq, the key with any tool is to know what they're used for and how to use them properly ;)

참고URL : https://stackoverflow.com/questions/9677445/mock-framework-vs-ms-fakes-frameworks

반응형