Rhino Mocks AAA 구문을 배우려고하는데 특정 메서드 (인수 값 포함)가 호출되었음을 증명하는 데 문제가 있습니다. 내 테스트 프레임 워크로 Machine.Specifications를 사용하고 있습니다.RhinoMock을 사용하여 세 가지 유형의 일반 메서드를 AssertWasCalled하는 방법은 무엇입니까?
이 특별한 방법은 일반적이므로 3 가지 유형으로 세 번 호출했는지 확인하고 싶습니다.
repo.Save<T1>(anything), repo.Save<T2>(anything), and repo.Save<T3>(anything)
각 유형마다 기능을 스터브했습니다. 그러나 나는 흥미로운 결과를 얻고있다. (아래)
[Subject("Test")]
public class When_something_happens_with_constraint
{
static IRepository repo;
static TestController controller;
static ActionResult result;
Establish context =() =>
{
repo = MockRepository.GenerateMock<IRepository>();
controller = new TestController(repo);
repo.Stub(o => o.Save<Something>(Arg<Something>.Is.Anything));
repo.Stub(o => o.Save<SomethingElse>(Arg<SomethingElse>.Is.Anything));
repo.Stub(o => o.Save<AnotherOne>(Arg<AnotherOne>.Is.Anything));
};
//post data to a controller
Because of =() => { result = controller.SaveAction(new SomethingModel() { Name = "test", Description = "test" }); };
//controller constructs its own something using the data posted, then saves it. I want to make sure three calls were made.
It Should_save_something =() => repo.AssertWasCalled(o => o.Save<Somethign>(Arg<Something>.Is.Anything));
It Should_save_something_else =() => repo.AssertWasCalled(o => o.Save<SomethingElse>(Arg<SomethingElse>.Is.Anything));
It Should_save_another_one =() => repo.AssertWasCalled(o => o.Save<AnotherOne>(Arg<AnotherOne>.Is.Anything));
}
결과는 두 가지 예외이며 합격입니다.
첫 번째 호출 예외 :
System.InvalidOperationException : 없음 기대가 확인하도록 설정 없었다 작업에서 메서드 호출이 가상 (C 번호)가 있는지 확인/재정의 (VB.Net) 메서드 호출을
두 번째 예외 :
System.InvalidOperationException : 사용의 Arg을 만 모의 메서드 호출 내에서 녹화하는 동안. 1 개의 인수가 예상되며 2 개가 정의됩니다.
세 번째 이유는 이상한 이유 때문입니다.
또한 내 설정에서 GenerateMock()을 사용하고 스텁과 함께 GenerateStub()를 사용하여 시도해 보았습니다. 둘 다 똑같은 결과를 가져 왔습니다. 나는 뭔가 잘못하고있을거야.
내가 사용하고 있습니다 : MachineSpec 0.3.0.0 및 RhinoMocks 3.6.0.0
어떤 아이디어?
----- 여기에 이명박의 도움으로 전체 (작업 버전)의 고정 ----------
. 여분의 (non-linq) 레이어를 사용하고 있습니다. 내 실제 문제는 내 테스트 중 하나가 오프라인 실제 코드에서 잘못된 람다 변수를 다시 사용한다는 것이 었습니다. It Should_do_something =() => repo.AssertWasCalled (o =>repo. 저장 (데이터)); // 나쁜 람다
그래서 여기에 올바른 테스트를위한 샘플이 있습니다.
using System;
using System.Linq;
using System.Collections.Generic;
using Machine.Specifications;
using Rhino.Mocks;
namespace OnlineTesting.Specifications
{
public interface Repository
{
void Save<T>(T data);
IQueryable<T> All<T>();
}
public interface Service
{
void SaveItem(Item data);
void SaveAnotherItem(AnotherItem data);
void SaveOtherItem(OtherItem data);
List<Item> GetItems();
List<AnotherItem> GetAnotherItems();
List<OtherItem> GetOtherItems();
}
public class ConcreteService : Service
{
Repository repo;
public ConcreteService(Repository repo)
{
this.repo = repo;
}
public void SaveItem(Item data)
{
repo.Save(data);
}
public void SaveAnotherItem(AnotherItem data)
{
repo.Save(data);
}
public void SaveOtherItem(OtherItem data)
{
repo.Save(data);
}
public List<Item> GetItems()
{
return repo.All<Item>().ToList();
}
public List<AnotherItem> GetAnotherItems()
{
return repo.All<AnotherItem>().ToList();
}
public List<OtherItem> GetOtherItems()
{
return repo.All<OtherItem>().ToList();
}
}
public class Item
{
public int Id { get; set; }
}
public class OtherItem
{
}
public class AnotherItem
{
}
public class When_something_else_happens
{
Establish context =() =>
{
_repository = MockRepository.GenerateMock<Repository>();
_service = new ConcreteService(_repository);
_controller = new TestController(_service);
_repository.Stub(o => o.Save<Item>(Arg<Item>.Is.Anything)).WhenCalled(
new Action<MethodInvocation>((o) =>
{
var data = o.Arguments.FirstOrDefault() as Item;
if (data != null && data.Id == 0)
data.Id++;
}));
};
Because of =() => _controller.DoSomethingElse();
It should_save_the_first_thing =() =>
_repository.AssertWasCalled(repo => repo.Save(Arg<Item>.Is.Anything));
It should_save_the_other_thing =() =>
_repository.AssertWasCalled(repo => repo.Save(Arg<OtherItem>.Is.Anything));
It should_save_the_last_thing =() =>
_repository.AssertWasCalled(repo => repo.Save(Arg<AnotherItem>.Is.Anything));
static Repository _repository;
static TestController _controller;
static Service _service;
}
public class TestController
{
readonly Service _service;
public TestController(Service service)
{
_service = service;
}
public void DoSomethingElse()
{
_service.SaveItem(new Item());
_service.SaveOtherItem(new OtherItem());
_service.SaveAnotherItem(new AnotherItem());
}
}
}
또한 컨트롤러 동작이 새 객체를 생성하여 리포지토리에 전달하기 때문에 호출하기 전에 인수를 설정할 수 없습니다. 그래서 저는 Arg을 사용하고 있습니다. 무엇이든지. repo.save가 특정 유형에 대해 호출되었는지 확인하려고합니다. –
Nathan