-
-
Save Rookian/1575568 to your computer and use it in GitHub Desktop.
public class UnitOfWork : IUnitOfWork | |
{ | |
private ObjectContext _db; | |
public UnitOfWork(ObjectContext db) | |
{ | |
_db = db; | |
} | |
public void Commit() | |
{ | |
_db.SaveChanges(); | |
} | |
public void Dispose() | |
{ | |
_db.Dispose(); | |
_db = null; | |
} | |
} | |
[Subject(typeof(BaseForm<>))] | |
public class When_disposing_form | |
{ | |
static PosForm PosForm; | |
static ObjectContext ObjectContext; | |
private static IUnitOfWork UnitOfWork; | |
private static IPosDeviceRepository PosDeviceRepository; | |
Establish context = () => | |
{ | |
ObjectContext = new ErsManagementEntities(); | |
UnitOfWork = A.Fake<UnitOfWork>(x => x.WithArgumentsForConstructor( | |
() => new UnitOfWork(ObjectContext))); | |
PosDeviceRepository = new PosDeviceRepository(ObjectContext); | |
}; | |
Because of = () => | |
{ | |
using (PosForm = new PosForm(null, null, null, null, UnitOfWork, PosDeviceRepository, null, null, null)) | |
{ | |
} | |
}; | |
It should_dispose_object_context = () => A.CallTo(() => UnitOfWork.Dispose()).MustHaveHappened(); | |
} |
Works for me. Mir ist nicht klar, warum du dich an eine konkrete Entity à la PosDevice
bindest, obwohl du
- die Basisform testest,
- ein Interface für deine Entities definiert hast.
Stell dir vor, irgendwann fliegt PosDevice
raus, plötzlich bricht ein Test der nichts mit PosDevice
s zu tun hat.
using System;
using FakeItEasy;
using Machine.Specifications;
namespace ClassLibrary2
{
public abstract class BaseForm<T> : IDisposable where T : class, IEntity
{
readonly IUnitOfWork _uow;
protected BaseForm(IUnitOfWork uow)
{
_uow = uow;
}
public BaseForm(IUnitOfWork uow, IRepository<T> repository)
{
_uow = uow;
}
public void Dispose()
{
_uow.Dispose();
}
}
public interface IEntity
{
}
public interface IRepository<T>
{
}
public interface IUnitOfWork : IDisposable
{
}
[Subject(typeof(BaseForm<>))]
public class When_closing_a_form
{
Establish context = () =>
{
UnitOfWork = A.Fake<IUnitOfWork>();
var repository = A.Fake<IRepository<IEntity>>();
Form = A.Fake<BaseForm<IEntity>>(x => x.WithArgumentsForConstructor(new object[] { UnitOfWork, repository }));
};
Because of = () => Form.Dispose();
It should_dispose_the_unit_of_work =
() => A.CallTo(() => UnitOfWork.Dispose()).MustHaveHappened();
static BaseForm<IEntity> Form;
static IUnitOfWork UnitOfWork;
}
}
Hast vollkommen recht Alex. Aber die generische Basisklasse erbt von Form und da Form selbst schon von IDisposable erbt, macht es keinen Sinn von IDisposable zu erben.
Das Problem liegt an der Form Klasse. Wobei mir nicht klar ist, was das konkrete Problem wirklich ist.
Okay, die Ableitung von Form
hatte ich tatsächlich übersehen.
Ja an der liegt es. Für mich scheint es so als ob FakeItEasy da nen Bug hat.
Das ist eher eine Usability Issue (kannst sie trotzdem gerne reporten). Ich habe FIE selbst kompiliert, das ist die Exception die der Dynamic Proxy Generator von Castle wirft:
Due to limitations in CLR, DynamicProxy was unable to successfully replicate non-inheritable attribute System.Security.Permissions.UIPermissionAttribute on ClassLibrary2.BaseForm`1[[ClassLibrary2.IEntity, ClassLibrary2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].ProcessMnemonic. To avoid this error you can chose not to replicate this attribute type by calling 'Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Security.Permissions.UIPermissionAttribute))'.
Sie wird dann fälschlicherweise in die Exception die du bekommst "umgewandelt" und damit maskiert. Zugriff auf die korrekte InnerException
wäre hier praktisch.
Befolgt man den Hinweis aus dem Exception Text geht's übrigens gleich weiter mit TargetInvocationException
die eine NullReferenceException
beinhaltet. Grund hierfür ist dass der ctor
von Form
auf irgendwelche Properties zugreift die nicht initialisiert sind (konkret: DefaultMargin
):
at Castle.Proxies.BaseForm`1Proxy.get_DefaultMargin()
at System.Windows.Forms.Control..ctor(Boolean autoInstallSyncContext)
at System.Windows.Forms.Control..ctor()
at System.Windows.Forms.ScrollableControl..ctor()
at System.Windows.Forms.ContainerControl..ctor()
at System.Windows.Forms.Form..ctor()
at ClassLibrary2.BaseForm`1..ctor(IUnitOfWork uow, IRepository`1 repository) in D:\Users\agross\Coding\.NET\ClassLibrary2\ClassLibrary2\Class1.cs:line 19
at Castle.Proxies.BaseForm`1Proxy..ctor(IInterceptor[] , IUnitOfWork , IRepository`1 )
Merke: Windows Forms zu faken is nich.
Hab ich gemacht. Selbes Problem.