Mocking DbEntityEntry - entity-framework-5

I am writing unit tests for my Generic Repository layer but i have some problems with DbEntityEntry.
My Update method is like below.
public virtual void Update(TEntity entityToUpdate) {
var entity = dbSet.Find(context.Entry<ITrackedEntity>(entityToUpdate).Entity.Id);
context.Entry(entity).CurrentValues.SetValues(entityToUpdate);
}
As you can see, context.Entry<TEntity>(TEntity entity) method is invoked by caller. So while unit tests this code throws null exception.
I had tried to mock context.Entry method but i couldn't because i couldn't provide return value.
My current test method is below
[Fact]
public void UpdateTest() {
AssetType _sample1 = new AssetType() {
AssetTypeID = 1,
IsContainer = true,
Name = "Sample 1"
};
IDbSet<AssetType> assetTypeDbSet = new FakeDbSet<AssetType>(_sample1);
Mock<IDbContext> mockContext = new Mock<IDbContext>();
mockContext.Setup(pc => pc.Set<AssetType>()).Returns(assetTypeDbSet);
_sample1.Name = "Sample 1.1";
var dbEntity = mockContext.Object.Entry<ITrackedEntity>(_sample1);
mockContext.Setup(p => p.Entry<ITrackedEntity>(It.IsAny<AssetType>())).Returns(dbEntity);
using(GenericRepository<AssetType> repo = new GenericRepository<AssetType>(mockContext.Object)) {
repo.Update(_sample1);
var result = repo.GetAll(0, 0);
Assert.Equal(1, result.Count);
var singleResult = repo.GetByID(1);
Assert.Equal(_sample1.Name, singleResult.Name);
}
}
I tried to get DbEntityEntry value by calling context.Entry<>() method at test but that wa returned null, too.
Also this class cannot be iniated with new operator. So i stucked..

And what is the point of unit testing this code? You fake the Find method, then you fake DbEntityEntry and there will be no real logic to test.
Anyway EF code is not unit testable in general. That is one reason why people believe that repository will help them because they mock / fake their repository when testing upper layer. Repository is then tested with integration tests to make sure that everything in EF and database works as expected.
You will not fake DbEntityEntry with Moq. Maybe with TypeMock Isolator or MS Fakes you will be able to do more but it is not needed in your sample code.

Related

StepVerifier::expectError accepts any exception in Spock

I'm testing a class that uses Spring Boot's webflux library, and I've encountered strange behavior with StepVerifier::expectError. Specifically, I can pass any type (even String!) to the method and the test passes. My method under test should respond with an error Mono for this particular test, and the mono should contain a custom exception. My understanding from this SO question is that I have the StepVerifier operating in the correct block. What is going wrong here?
Class under test:
#Service
#RequiredArgsConstructor
public class PaymentsBO {
private final ContractClient contractClient;
public Mono<Void> updatePaymentInfo(Request record) {
return contractClient
.getContract(UUID.fromString(record.getContractUuid()))
.onErrorResume(throwable -> Mono.error(() -> new CustomException(
"Contract Service responded with a non-200 due to "
+ throwable.getCause())))
.flatMap(
// happy-path logic
);
}
}
Unit test:
def "Returns an error if the Contract Service returns a non-200"() {
given:
def testSubject = new PaymentsBO(contractServiceMock)
def contractServiceMock = Mock(ContractClient)
when:
def result = testSubject.updatePaymentInfo(record)
and:
StepVerifier.create(result)
.expectError(String.class)
then:
1 * contractServiceMock.getContract(CONTRACT_UUID) >> Mono.error(new ContractServiceException())
}
In StepVerifier docs we can read that verification must be triggered by calling one ot the verify methods
Trigger the verification of the resulting StepVerifier on its Publisher using either verify() or verify(Duration). (note some of the terminal expectations above have a "verify" prefixed alternative that both declare the expectation and trigger the verification).
https://projectreactor.io/docs/test/release/api/reactor/test/StepVerifier.html
Your code doesn't use a verify method.
Please consider these two cases:
#Test
void without_verify() {
Mono.error(new IllegalArgumentException(""))
.as(StepVerifier::create)
.expectError(NullPointerException.class);
}
#Test
void with_verify() {
Mono.error(new IllegalArgumentException(""))
.as(StepVerifier::create)
.expectError(NullPointerException.class)
.verify();
}
without_verify is passing because no verification has been triggered.
with_verify is failing because verification has been triggered.

CRM 2011 PLUGIN to update another entity

My PLUGIN is firing on Entity A and in my code I am invoking a web service that returns an XML file with some attributes (attr1,attr2,attr3 etc ...) for Entity B including GUID.
I need to update Entity B using the attributes I received from the web service.
Can I use Service Context Class (SaveChanges) or what is the best way to accomplish my task please?
I would appreciate it if you provide an example.
There is no reason you need to use a service context in this instance. Here is basic example of how I would solve this requirement. You'll obviously need to update this code to use the appropriate entities, implement your external web service call, and handle the field updates. In addition, this does not have any error checking or handling as should be included for production code.
I made an assumption you were using the early-bound entity classes, if not you'll need to update the code to use the generic Entity().
class UpdateAnotherEntity : IPlugin
{
private const string TARGET = "Target";
public void Execute(IServiceProvider serviceProvider)
{
//PluginSetup is an abstraction from: http://nicknow.net/dynamics-crm-2011-abstracting-plugin-setup/
var p = new PluginSetup(serviceProvider);
var target = ((Entity) p.Context.InputParameters[TARGET]).ToEntity<Account>();
var updateEntityAndXml = GetRelatedRecordAndXml(target);
var relatedContactEntity =
p.Service.Retrieve(Contact.EntityLogicalName, updateEntityAndXml.Item1, new ColumnSet(true)).ToEntity<Contact>();
UpdateContactEntityWithXml(relatedContactEntity, updateEntityAndXml.Item2);
p.Service.Update(relatedContactEntity);
}
private static void UpdateContactEntityWithXml(Contact relatedEntity, XmlDocument xmlDocument)
{
throw new NotImplementedException("UpdateContactEntityWithXml");
}
private static Tuple<Guid, XmlDocument> GetRelatedRecordAndXml(Account target)
{
throw new NotImplementedException("GetRelatedRecordAndXml");
}
}

AssertWasCalled on method in SystemUnderTest

I'm getting into TDD; using nUnit and RhinoMocks 3.5.
I'm trying to figure out how to AssertWasCalled on a method in the SystemUnderTest (SUT). My understanding is that you can't mock the system under test. In fact, my current test results in an exception because the I'm using the AssertWasCalled on the SUT.
OrdersPresenter:
public void OnViewLoad_GetOrders()
{
var orders = GetOrders();
View.Model.Orders = orders;
}
public List<Orders> GetOrders()
{
return _ordersRepository.GetAll();
}
OrdersPresenterTest:
_ordersPresenter = new OrdersPresenter(_view, _ordersRepository);
[Test]
public void OnViewLoad_GetOrders_Should_Call_GetOrders()
{
_view.Raise(v => v.LoadOrders += _ordersPresenter.OnViewLoad_GetOrders, view, new EventArgs);
_ordersPresenter.AssertWasCalled(d => d.GetOrders); // Getting non-mock exception here
}
How do I Assert GetOrders was called in the SUT? I haven't been able to figure it out in the docs.
Any help is greatly appreciated.
Edit:
I understand the GetOrders method in the SUT should be private. I went back thru Roy Osherove's Art of Unit Testing to see how to test private methods. Roy says making a method public (to test against) is not necessarily a bad thing, so I will keep it public.
So I've written a test for GetOrders and I assert the return value ShouldBe a list of orders. That said, I believe I need to restructure my test for OnViewLoad_GetOrders by stubbing the value I get from GetOrders and asserting the results of my actions on that object.
Can someone confirm and explain?
You can not use AssertWasCalled() on not-mocked objects. Just abstract class OrdersPresenter by an interface (use Extract Interface refactoring technique) and then
var ordersPresenter = MockRepository.GenerateMock<IOrderRepository>();
view.Raise(...);
_ordersPresenter.AssertWasCalled(d => d.GetOrders);
BTW,
for me it is not clear why RhinoMocks not used generic parameter constraint for AssertWasCalled
public static void AssertWasCalled<T>(this T mock, Action<T> action,
Action<IMethodOptions<object>> setupConstraints)
Basically T is not limited, but I believe it would be better limit it to somethign like IMockMarkerInterface

Implementing Reliable Inter-Role Communication using the AppFabric ServiceBus on Azure, IObserver pattern

I have been trying to follow this example (download the source code from a link on the site or here, but I keep running into an error that seems embedded in the example.
My procedure has been as follows (after installing the AppFabric SDK and other dependencies):
Download the source
Create a Service Namespace on the AppFabric.
Import the project into a new Windows Azure project with one Worker Role, make sure that it all compiles and that the default Worker Role Run() method starts and functions.
Configure the method GetInterRoleCommunicationEndpoint in InterRoleCommunicationExtension.cs with the ServiceNameSpace and IssuerSecret from my AppFabric Service Namespace (IssuerName and ServicePath stay default). This is a hard-wiring of my own parameters.
Copy/paste the initialization logic from the "SampleWorkerRole.cs" file in the demo into the OnStart() method of my project's Worker Role
Comment-out references to Tracemanager.* as the demo code does not have the Tracemanager methods implemented and they're not crucial for this test to work. There are about 7-10 of these references (just do a Find -> "Tracemanager" in entire solution).
Build successfully.
Run on local Compute Emulator.
When I run this test, during the initialization of a new InterRoleCommunicationExtension (the first piece of the inter-role communication infrastructure to be initialized, this.interRoleCommunicator = new InterRoleCommunicationExtension();), an error is raised: "Value cannot be null. Parameter name: contractType."
Drilling into this a bit, I follow the execution down to the following method in ServiceBusHostFactory.cs (one of the files from the sample):public static Type GetServiceContract(Type serviceType)
{
Guard.ArgumentNotNull(serviceType, "serviceType");
Type[] serviceInterfaces = serviceType.GetInterfaces();
if (serviceInterfaces != null && serviceInterfaces.Length > 0)
{
foreach (Type serviceInterface in serviceInterfaces)
{
ServiceContractAttribute serviceContractAttr = FrameworkUtility.GetDeclarativeAttribute<ServiceContractAttribute>(serviceInterface);
if (serviceContractAttr != null)
{
return serviceInterface;
}
}
}
return null;
}
The serviceType parameter's Name property is "IInterRoleCommunicationServiceContract," which is one of the classes of the demo, and which extends IObservable. The call to serviceType.GetInterfaces() returns the "System.IObservable`1" interface, which is then passed into FrameworkUtility.GetDeclarativeAttribute(serviceInterface);, which has the following code:
public static IList GetDeclarativeAttributes(Type type) where T : class
{
Guard.ArgumentNotNull(type, "type");
object[] customAttributes = type.GetCustomAttributes(typeof(T), true);
IList<T> attributes = new List<T>();
if (customAttributes != null && customAttributes.Length > 0)
{
foreach (object customAttr in customAttributes)
{
if (customAttr.GetType() == typeof(T))
{
attributes.Add(customAttr as T);
}
}
}
else
{
Type[] interfaces = type.GetInterfaces();
if (interfaces != null && interfaces.Length > 0)
{
foreach (object[] customAttrs in interfaces.Select(iface => iface.GetCustomAttributes(typeof(T), false)))
{
if (customAttrs != null && customAttrs.Length > 0)
{
foreach (object customAttr in customAttrs)
{
attributes.Add(customAttr as T);
}
}
}
}
}
return attributes;
}</code><br>
It is here that the issue arises. After not finding any customAttributes on the "IObservable1" type, it calls type.GetInterfaces(), expecting a return. Even though type is "System.IObservable1," this method returns an empty array, which causes the function to return null and the exception with the above message to be raised.
I am extremely interested in getting this scenario working, as I think the Publish/Subscribe messaging paradigm is the perfect solution for my application. Has anyone been able to get this demo code (from the AppFabric CAT Team itself!) working, or can spot my error? Thank you for your help.
Answered in the original blog post (see link below). Please advise if you are still experiencing problems. We are committed to supporting our samples on best effort basis.
http://blogs.msdn.com/b/appfabriccat/archive/2010/09/30/implementing-reliable-inter-role-communication-using-windows-azure-appfabric-service-bus-observer-pattern-amp-parallel-linq.aspx#comments

subsonic unit testing bug?

I'm currently using Subsonic 3.03 Active Record repository.
I have setup a Test connection string to utilise the dummy internal storage.
[TestInitialize]
public void TestInitialize()
{
List<ServiceJob> jobs = new List<ServiceJob>()
{
new ServiceJob() { ServiceJobID = 1 },
new ServiceJob() { ServiceJobID = 2 }
};
ServiceJob.Setup(jobs);
}
[TestMethod]
public void TestMethod()
{
ServiceJob job = ServiceJob.SingleOrDefault(s => s.ServiceJobID == 2);
Assert.AreEqual(2, job.ServiceJobID);
}
I'm expecting this unit-test to pass, but it pulls out the first service job and fails.
I've also experienced problems using other sugar methods such as .Find().
It works fine when using the IQueryable interface such as ServiceJob.All.Where(s => s.ServiceJobID == 2) but don't fancy stripping out the sugar for testing purposes!
Great product by the way, really impressed so far.
As you say this looks like it's definitely a bug. You should submit it as an issue to github:
http://github.com/subsonic/SubSonic-3.0/issues

Resources