KB Article T854049
Visible to All Users

How to unit test localized strings from CaptionHelper (Approach 2)

Test Scenario
Our task is the same as the one described in the How to unit test localized strings from CaptionHelper (Approach 1) article. We, however, will use another approach to test if our localized string is correctly applied.

Unit Test Implementation
Imagine we added a localization item and we want to test if CaptionHelper returns a correct localized string.

XML
<Application Title="MySolution"> <Localization> <LocalizationGroup Name="Messages"> <LocalizationItem Name="Test" Value="Test" IsNewNode="True" /> </LocalizationGroup> </Localization> </Application>

Our test will be:

C#
using DevExpress.ExpressApp; using DevExpress.ExpressApp.Core; using DevExpress.ExpressApp.DC; using DevExpress.ExpressApp.Utils; using Moq; using NUnit.Framework; using MySolution.Module; namespace MySolution.Tests { [TestFixture] public class CaptionHelperTests { [Test] public void Test2() { Assert.AreEqual("Test", CaptionHelper.GetLocalizedText("Messages", "Test")); } } }
Visual Basic
Imports DevExpress.ExpressApp Imports DevExpress.ExpressApp.Core Imports DevExpress.ExpressApp.DC Imports DevExpress.ExpressApp.Utils Imports Moq Imports NUnit.Framework Imports MySolution.[Module] <TestFixture> Public Class CaptionHelperTests <Test> Public Sub Test2() Assert.AreEqual("Test", CaptionHelper.GetLocalizedText("Messages", "Test")) End Sub End Class

From How to unit test localized strings from CaptionHelper (Approach 1) we know that we need to call the CaptionHelper.Setup method to make our test work. XafApplication calls this method from the SetupModelApplication private method. And SetupModelApplication is called from the XafApplication Setup public method. Thus, to make our test work, we just need to call the Setup method in it. We won't create a real XafApplication - it's a time and memory consuming operation. We will mock it.

C#
var applicationMock = new Mock<XafApplication>(); applicationMock.CallBase = true;
Visual Basic
Dim applicationMock = New Mock(Of XafApplication)() applicationMock.CallBase = True

We need to set the Mock<T>.CallBase property to true to be able to use real method implementations of the XafApplication class. The Setup method has the following signature:

C#
public void Setup(ExpressApplicationSetupParameters parameters);

Thus, we need to create an ExpressApplicationSetupParameters object. Its constructor is:

C#
public ExpressApplicationSetupParameters(string applicationName, IObjectSpaceProvider objectSpaceProvider, ControllersManager controllersManager, ModuleList modules);

We are not interested in the application name and will pass null/Nothing to this parameter. Then, we need an IObjectSpaceProvider instance - we will mock it. We will create a ControllersManager instance and create a ModuleList with our Module.

C#
ModuleList moduleList = new ModuleList { new MySolutionModule() }; var objectSpaceProviderMock = new Mock<IObjectSpaceProvider>(); ExpressApplicationSetupParameters setupParameters = new ExpressApplicationSetupParameters(null, objectSpaceProviderMock.Object, new ControllersManager(), moduleList); applicationMock.Object.Setup(setupParameters);
Visual Basic
Dim moduleList As ModuleList = New ModuleList From { New MySolutionModule() } Dim objectSpaceProviderMock = New Mock(Of IObjectSpaceProvider)() Dim setupParameters As ExpressApplicationSetupParameters = New ExpressApplicationSetupParameters(Nothing, objectSpaceProviderMock.Object, New ControllersManager(), moduleList) applicationMock.Object.Setup(setupParameters)

Now, run our test. It fails with the following message and call stack:

Code
Value cannot be null. Parameter name: entityStore
Call Stack
DevExpress.Data.v19.2.dll!DevExpress.Utils.Guard.ThrowArgumentNullException(string propName) Line 108 C# DevExpress.Data.v19.2.dll!DevExpress.Utils.Guard.ArgumentNotNull(object value, string name) Line 51 C# DevExpress.ExpressApp.v19.2.dll!DevExpress.ExpressApp.Utils.Guard.ArgumentNotNull(object argumentValue, string argumentName) Line 58 C# DevExpress.ExpressApp.v19.2.dll!DevExpress.ExpressApp.DC.TypesInfo.AddEntityStore(DevExpress.ExpressApp.DC.IEntityStore entityStore) Line 228 C# DevExpress.ExpressApp.v19.2.dll!DevExpress.ExpressApp.XafApplication.AddEntityStoresIntoTypesInfo() Line 424 C# DevExpress.ExpressApp.v19.2.dll!DevExpress.ExpressApp.XafApplication.Setup(DevExpress.ExpressApp.ExpressApplicationSetupParameters parameters) Line 1589 C#

This happens because there is a check in the AddEntityStore method that the passed entityStore parameter is not null.

C#
public void AddEntityStore(IEntityStore entityStore) { Guard.ArgumentNotNull(entityStore, "entityStore"); // ... }

It's null in our case. The XafApplication method that calls the AddEntityStore method is AddEntityStoresIntoTypesInfo. Its implementation is:

C#
private void AddEntityStoresIntoTypesInfo() { TypesInfo localTypesInfo = typesInfo as TypesInfo; if(localTypesInfo != null) { foreach(IObjectSpaceProvider objectSpaceProvider in objectSpaceProviders) { localTypesInfo.AddEntityStore(objectSpaceProvider.EntityStore); } } }

Thus, the IObjectSpaceProvider instance we mocked does not have its EntityStore specified. Let's mock this property.

C#
var entityStoreMock = new Mock<IEntityStore>(); objectSpaceProviderMock.Setup(o => o.EntityStore).Returns(entityStoreMock.Object);
Visual Basic
Dim entityStoreMock = New Mock(Of IEntityStore)() objectSpaceProviderMock.Setup(Function(o) o.EntityStore).Returns(entityStoreMock.Object)

Now, our test passes. Its entire code:

C#
[Test] public void Test2() { var applicationMock = new Mock<XafApplication>(); applicationMock.CallBase = true; ModuleList moduleList = new ModuleList { new MySolutionModule() }; var entityStoreMock = new Mock<IEntityStore>(); var objectSpaceProviderMock = new Mock<IObjectSpaceProvider>(); objectSpaceProviderMock.Setup(o => o.EntityStore).Returns(entityStoreMock.Object); ExpressApplicationSetupParameters setupParameters = new ExpressApplicationSetupParameters(null, objectSpaceProviderMock.Object, new ControllersManager(), moduleList); applicationMock.Object.Setup(setupParameters); Assert.AreEqual("Test", CaptionHelper.GetLocalizedText("Messages", "Test")); }
Visual Basic
<Test> Public Sub Test2() Dim applicationMock = New Mock(Of XafApplication)() applicationMock.CallBase = True Dim moduleList As ModuleList = New ModuleList From { New MySolutionModule() } Dim entityStoreMock = New Mock(Of IEntityStore)() Dim objectSpaceProviderMock = New Mock(Of IObjectSpaceProvider)() objectSpaceProviderMock.Setup(Function(o) o.EntityStore).Returns(entityStoreMock.Object) Dim setupParameters As ExpressApplicationSetupParameters = New ExpressApplicationSetupParameters(Nothing, objectSpaceProviderMock.Object, New ControllersManager(), moduleList) applicationMock.Object.Setup(setupParameters) Assert.AreEqual("Test", CaptionHelper.GetLocalizedText("Messages", "Test")) End Sub

See Also:
This series contains the following articles:

  1. How to write unit tests for XAF Actions, Controllers, and other custom UI logic
  2. How to unit test Action's enabled/disabled state based on user permissions
  3. How to unit test whether object property changes via Actions were successfully committed
  4. How to unit test object queries by criteria and Detail View creation
  5. How to unit test event handlers in Controllers
  6. How to unit test New Action's custom business logic based on parent and nested Views
  7. How to unit test Action's enabled/disabled state based on target criteria and selection dependency types in List View
  8. How to unit test Action's enabled/disabled state based on target criteria and selection dependency types in Detail View
  9. How to unit test localized strings from CaptionHelper (Approach 1)
  10. How to unit test localized strings from CaptionHelper (Approach 2) (current)
  11. How to unit test custom logic in XAF/XPO business classes

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.