File: DatabaseInitializerTracker.cs

package info (click to toggle)
mono-reference-assemblies 3.12.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 604,240 kB
  • ctags: 625,505
  • sloc: cs: 3,967,741; xml: 2,793,081; ansic: 418,042; java: 60,435; sh: 14,833; makefile: 11,576; sql: 7,956; perl: 1,467; cpp: 1,446; yacc: 1,203; python: 598; asm: 422; sed: 16; php: 1
file content (122 lines) | stat: -rw-r--r-- 5,400 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

namespace System.Data.Entity
{
    using System.Data.Entity.Core.Objects;
    using System.Data.Entity.Internal;
    using System.Data.Entity.Resources;
    using System.Text;
    using Moq;
    using Moq.Protected;

    /// <summary>
    ///     Helper class that uses Moq to create mocks for the InternalContext and related classes such
    ///     that different database initialization strategies can be tested and the operations that these
    ///     strategies perform can be recorded and validated.
    /// </summary>
    public class DatabaseInitializerTracker<TContext, TInitializer>
        where TInitializer : class, IDatabaseInitializer<TContext>
        where TContext : DbContext, new()
    {
        private readonly StringBuilder _operations = new StringBuilder();

        private readonly Mock<InternalContextForMock<TContext>> _mockInternalContext;
        private readonly Mock<DatabaseOperations> _mockDatabaseOps;
        private readonly Mock<TContext> _mockDbContext;
        private readonly Mock<TInitializer> _mockStrategy;
        private bool _databaseExists;

        public DatabaseInitializerTracker(bool databaseExists, bool modelCompatible = true, bool hasMetadata = true)
        {
            _databaseExists = databaseExists;
            _mockInternalContext = new Mock<InternalContextForMock<TContext>>
                                       {
                                           CallBase = true
                                       };
            _mockDatabaseOps = new Mock<DatabaseOperations>();
            _mockDbContext = Mock.Get((TContext)_mockInternalContext.Object.Owner);

            _mockInternalContext.Setup(c => c.DatabaseOperations).Returns(_mockDatabaseOps.Object);
            _mockInternalContext.Setup(c => c.DefaultInitializer).Returns(new CreateDatabaseIfNotExists<DbContext>());
            _mockInternalContext.Setup(c => c.CreateDatabase(It.IsAny<ObjectContext>())).Callback(
                () =>
                    {
                        _databaseExists = true;
                        _operations.Append("CreateDatabase ");
                    });

            _mockDatabaseOps.Setup(d => d.Create(It.IsAny<ObjectContext>())).Callback(
                () =>
                    {
                        _databaseExists = true;
                        _operations.Append("Create ");
                    });

            _mockDatabaseOps.Setup(d => d.Exists(It.IsAny<ObjectContext>())).Callback(() => _operations.Append("Exists ")).Returns(
                DatabaseExists);
            _mockDatabaseOps.Setup(d => d.DeleteIfExists(It.IsAny<ObjectContext>())).Callback(() => _operations.Append("DeleteIfExists ")).
                Returns(DeleteIfExists);

            _mockInternalContext.Setup(c => c.UseTempObjectContext()).Callback(() => _operations.Append("UseTempObjectContext "));
            _mockInternalContext.Setup(c => c.DisposeTempObjectContext()).Callback(() => _operations.Append("DisposeTempObjectContext "));
            _mockInternalContext.Setup(c => c.SaveMetadataToDatabase()).Callback(() => _operations.Append("SaveMetadataToDatabase "));

            _mockInternalContext.Setup(c => c.CompatibleWithModel(It.IsAny<bool>())).Callback(
                (bool throwIfNoMetadata) =>
                    {
                        if (!hasMetadata && throwIfNoMetadata)
                        {
                            throw Error.Database_NoDatabaseMetadata();
                        }
                    }).Returns(modelCompatible);

            _mockInternalContext.Setup(c => c.CreateObjectContextForDdlOps()).Returns(new Mock<ClonedObjectContext>().Object);
            _mockInternalContext.SetupGet(c => c.ProviderName).Returns("Dummy.Data.Provider");

            _mockStrategy = new Mock<TInitializer>
                                {
                                    CallBase = true
                                };
            _mockStrategy.Protected().Setup("Seed", ItExpr.IsAny<TContext>()).Callback(() => _operations.Append("Seed "));
        }

        private bool DeleteIfExists()
        {
            var exists = _databaseExists;
            _databaseExists = false;
            return exists;
        }

        private bool DatabaseExists()
        {
            return _databaseExists;
        }

        public void ExecuteStrategy()
        {
            _mockStrategy.Object.InitializeDatabase(_mockDbContext.Object);
        }

        public void RegisterStrategy()
        {
            var mockContextType = _mockDbContext.Object.GetType();
            var initMethod = typeof(Database).GetMethod("SetInitializer").MakeGenericMethod(mockContextType);
            initMethod.Invoke(null, new object[] { _mockStrategy.Object });
        }

        public string Result
        {
            get { return _operations.ToString().Trim(); }
        }

        public TContext Context
        {
            get { return _mockDbContext.Object; }
        }

        internal Mock<InternalContextForMock<TContext>> MockInternalContext
        {
            get { return _mockInternalContext; }
        }
    }
}