Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

281 lines
12 KiB
C#

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace ProductivityApiUnitTests
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Internal;
using System.Data.Entity.Internal.MockingProxies;
using System.Data.SqlClient;
using System.Reflection;
using Moq;
using Xunit;
public class ClonedObjectContextTests : TestBase
{
[Fact]
public void Creating_a_cloned_ObjectContext_causes_the_store_and_entity_connection_to_be_cloned_and_given_connection_string_applied(
)
{
var storeConnection = new SqlConnection();
var mockConnection = CreateMockConnection(storeConnection);
var mockContext = CreateMockObjectContext(mockConnection);
new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
mockConnection.Verify(
m =>
m.CreateNew(
It.Is<SqlConnection>(
p =>
p != null && !ReferenceEquals(p, storeConnection) &&
p.ConnectionString == "Database=PinkyDinkyDo")));
}
[Fact]
public void Cloning_an_ObjectContext_with_a_default_container_name_copies_that_container_name()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
mockContext.Setup(m => m.DefaultContainerName).Returns("Kipper");
var clonedContext = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
mockClonedContext.VerifySet(m => m.DefaultContainerName = It.IsAny<string>());
Assert.Equal("Kipper", clonedContext.ObjectContext.DefaultContainerName);
}
[Fact]
public void Cloning_an_ObjectContext_with_a_null_default_container_name_results_in_a_clone_without_a_default_container_name()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
var clonedContext = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
mockClonedContext.VerifySet(m => m.DefaultContainerName = It.IsAny<string>(), Times.Never());
Assert.Null(clonedContext.ObjectContext.DefaultContainerName);
}
[Fact]
public void Cloning_an_ObjectContext_with_a_whitespace_default_container_name_results_in_a_clone_without_a_default_container_name()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
mockContext.Setup(m => m.DefaultContainerName).Returns(" ");
var clonedContext = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
mockClonedContext.VerifySet(m => m.DefaultContainerName = It.IsAny<string>(), Times.Never());
Assert.Null(clonedContext.ObjectContext.DefaultContainerName);
}
[Fact]
public void ClonedObjectContext_Connection_returns_the_cloned_store_connection()
{
var storeConnection = new SqlConnection();
var mockContext = CreateMockObjectContext(CreateMockConnection(storeConnection));
var clonedConnection = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo").Connection;
Assert.NotSame(storeConnection, clonedConnection);
Assert.Equal("Database=PinkyDinkyDo", clonedConnection.ConnectionString);
Assert.Same(storeConnection.GetType(), clonedConnection.GetType());
}
[Fact]
public void ClonedObjectContext_ObjectContext_returns_the_cloned_ObjectContext()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
var clonedContext = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
mockContext.Verify(m => m.CreateNew(It.IsAny<EntityConnectionProxy>()));
Assert.Same(mockClonedContext.Object, clonedContext.ObjectContext);
}
[Fact]
public void When_cloning_an_ObjectContext_without_transfering_assemblies_no_assemblies_are_transfered()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
new ClonedObjectContext(
mockContext.Object, "Database=PinkyDinkyDo",
transferLoadedAssemblies: false);
mockContext.Verify(m => m.GetObjectItemCollection(), Times.Never());
mockClonedContext.Verify(m => m.LoadFromAssembly(It.IsAny<Assembly>()), Times.Never());
}
[Fact]
public void
When_cloning_an_ObjectContext_with_assemblies_enum_complex_and_entity_type_assemblies_are_transfered_but_others_are_ignored()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
mockContext.Verify(m => m.GetObjectItemCollection(), Times.Once());
mockClonedContext.Verify(m => m.LoadFromAssembly(It.Is<Assembly>(a => a.FullName == "ComplexType Assembly")));
mockClonedContext.Verify(m => m.LoadFromAssembly(It.Is<Assembly>(a => a.FullName == "EntityType Assembly")));
mockClonedContext.Verify(m => m.LoadFromAssembly(It.Is<Assembly>(a => a.FullName == "EnumType Assembly")));
}
[Fact]
public void Disposing_a_cloned_ObjectContext_disposes_both_the_context_and_the_connection()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
var clonedContext = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
var connectionIsDisposed = false;
clonedContext.Connection.Disposed += (_, __) => connectionIsDisposed = true;
clonedContext.Dispose();
mockClonedContext.Verify(m => m.Dispose());
Assert.True(connectionIsDisposed);
}
[Fact]
public void Calling_Dispose_on_an_already_disposed_cloned_ObjectContext_does_nothing()
{
var mockClonedContext = new Mock<ObjectContextProxy>();
var mockContext = CreateMockObjectContext(CreateMockConnection(), mockClonedContext);
var clonedContext = new ClonedObjectContext(mockContext.Object, "Database=PinkyDinkyDo");
var connectionIsDisposed = false;
clonedContext.Connection.Disposed += (_, __) => connectionIsDisposed = true;
clonedContext.Dispose();
connectionIsDisposed = false;
clonedContext.Dispose();
mockClonedContext.Verify(m => m.Dispose(), Times.Once());
Assert.False(connectionIsDisposed);
}
private Mock<EntityConnectionProxy> CreateMockConnection(SqlConnection storeConnection = null)
{
storeConnection = storeConnection ?? new SqlConnection();
var mockConnection = new Mock<EntityConnectionProxy>();
mockConnection.Setup(m => m.StoreConnection).Returns(storeConnection);
mockConnection.Setup(m => m.CreateNew(It.IsAny<SqlConnection>())).Returns<SqlConnection>(
c =>
{
var mockClonedConnection = new Mock<EntityConnectionProxy>();
mockClonedConnection.Setup(cc => cc.StoreConnection).Returns(c);
return mockClonedConnection.Object;
});
return mockConnection;
}
private Mock<ObjectContextProxy> CreateMockObjectContext(
Mock<EntityConnectionProxy> mockConnection = null, Mock<ObjectContextProxy> mockClonedContext = null)
{
mockConnection = mockConnection ?? CreateMockConnection();
mockClonedContext = mockClonedContext ?? new Mock<ObjectContextProxy>();
mockClonedContext.SetupProperty(m => m.DefaultContainerName);
var mockContext = new Mock<ObjectContextProxy>();
mockContext.Setup(m => m.Connection).Returns(mockConnection.Object);
mockContext.Setup(m => m.GetObjectItemCollection()).Returns(
new List<GlobalItem>
{
CreateFakeComplexType(),
CreateFakeEntityType(),
CreateFakeEnumType(),
CreateFakePrimitiveType(),
});
// Ensure fake EDM types have fake CLR types and assemblies
SetupMockStructuralType<ComplexType>(mockContext);
SetupMockStructuralType<EntityType>(mockContext);
SetupMockEnumType(mockContext);
mockContext.Setup(m => m.CreateNew(It.IsAny<EntityConnectionProxy>())).Returns<EntityConnectionProxy>(
c =>
{
mockClonedContext.Setup(cc => cc.Connection).Returns(c);
return mockClonedContext.Object;
});
return mockContext;
}
private void SetupMockStructuralType<TEdmType>(Mock<ObjectContextProxy> mockContext) where TEdmType : StructuralType
{
var mockClrType = new Mock<Type>();
mockClrType.Setup(m => m.Assembly).Returns(new FakeAssembly(typeof(TEdmType).Name + " Assembly"));
mockContext.Setup(m => m.GetClrType(It.IsAny<TEdmType>())).Returns(mockClrType.Object);
}
private void SetupMockEnumType(Mock<ObjectContextProxy> mockContext)
{
var mockClrType = new Mock<Type>();
mockClrType.Setup(m => m.Assembly).Returns(new FakeAssembly("EnumType Assembly"));
mockContext.Setup(m => m.GetClrType(It.IsAny<EnumType>())).Returns(mockClrType.Object);
}
private ComplexType CreateFakeComplexType()
{
return (ComplexType)Activator.CreateInstance(typeof(ComplexType), nonPublic: true);
}
private EnumType CreateFakeEnumType()
{
return (EnumType)Activator.CreateInstance(typeof(EnumType), nonPublic: true);
}
private PrimitiveType CreateFakePrimitiveType()
{
return (PrimitiveType)Activator.CreateInstance(typeof(PrimitiveType), nonPublic: true);
}
private EntityType CreateFakeEntityType()
{
const BindingFlags bindingFlags = BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Instance;
return (EntityType)Activator.CreateInstance(
typeof(EntityType),
bindingFlags,
null,
new object[] { "FakeEntity", "FakeNamespace", DataSpace.OSpace },
null);
}
/// <summary>
/// Used because Moq cannot mock Assembly.
/// </summary>
public class FakeAssembly : Assembly
{
private readonly string _name;
public FakeAssembly(string name)
{
_name = name;
}
public override string FullName
{
get { return _name; }
}
}
}
}