Rhino Mocks AAA sözdizimini öğrenmeye çalışıyorum ve belirli bir yöntemin (herhangi bir argüman değeriyle) çağrıldığını sorun yaşıyorum. Test framework'üm olarak Machine.Specifications kullanıyorum.RhinoMocks kullanarak üç farklı türden genel bir yöntem nasıl kullanılır?
Bu özel yöntem geneldir ve üç farklı türde üç kez çağrıldığından emin olmak istiyorum.
repo.Save<T1>(anything), repo.Save<T2>(anything), and repo.Save<T3>(anything)
Her tür için işlevi durdurdum. Ama ilginç bir sonuç alıyorum. (aşağıdaki)
[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));
}
Sonuç iki istisna ve bir geçiştir.
ilk çağrı atar:
System.InvalidOperationException: Hiçbir beklentileri doğrulanacak kurulum vardı eylemde yöntem çağrısı sanal (C#) olmasını sağlamak/geçersiz kılınabilir (VB.Net) yöntemi çağrısı
ikincisi atar:
System.InvalidOperationException: Kullanım Arg SADECE sahte yöntem çağrı içinde kayıt sırasında. 1 argüman bekleniyor, 2 tane tanımlandı.
Üçüncüsü, bazı garip nedenlerden dolayı geçer.
Ayrıca, kurulumumda GenerateMock() ile Expect'i kullanmayı ve Stub ile GenerateStub() öğesini kullanmayı denedim. Her ikisi de aynı sonuçla sona erdi. Yanlış bir şey yapmalıyım.
kullanıyorum: MachineSpec 0.3.0.0 ve 3.6.0.0 RhinoMocks
Herhangi bir fikir?
----- İşte Lee'nin yardımıyla tam (çalışma versiyonu) var SABİT ----------
. Ekstra (linq olmayan) bir katman kullanıyorum. Benim asıl sorun benim testlerimden birinin çevrimdışı gerçek kodda yanlış lambda değişkenini tekrar kullanmasıydı. It Should_do_something =() => repo.AssertWasCalled (o =>repo .Save (veri)); // bad lambda
İşte referans için doğru test örneği.
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());
}
}
}
Ayrıca ... Denetleyici eylemi yeni bir nesne oluşturduğundan ve depoya geçirdiğinden, aramadan önce bağımsız değişkenleri ayarlayamıyorum. Bu yüzden Arg .Is.Anything kullanıyorum. Ben sadece belirli bir tür için repo.save çağrıldığından emin olmak istiyorum. –
Nathan