System.ArgumentException : Duplicate type name within an assembly #1247
-
I have created two razor test files, each testing a different component but sharing some of the same services (like a Window, Dialog, etc. Service). public static void MockServices(this IServiceCollection services)
{
services.AddScoped<IDialogService, DialogService>();
services.AddScoped<IFormService, MockFormService>();
services.AddScoped<IMenuService, MockMenuService>();
} Then in the first razor test file (Form1Tests.razor): @inherits TestContext
@code {
public Form1Tests() {
Services.MockServices();
JSInterop.Mode = JSRuntimeMode.Loose;
RenderTree.Add<MainLayout>();
}
// Example Test method
public async void PartialFormExit_ShouldPromptUserAboutUnsavedChanges() {
// [Arrange]
var cut = Render(
@<TelerikRootComponent>
<TelerikDialog />
<FormComponent1 />
</TelerikRootComponent>
);
FormService formService = Services.GetRequiredService<FormService>();
formService.Form.FirstField = "Test";
var formComponent1 = cut.FindComponent<FormComponent1>();
FieldIdentifier fieldIdentifier = FormService.EditContext.Field(nameof(Form.FirstField));
await formComponent1.InvokeAsync(() => formService.EditContext.NotifyFieldChanged(fieldIdentifier));
// [Act]
cut.Find("button[name='cancel']").Click();
cut.WaitForState(() => cut.Find("div.k-dialog-title") != null);
TelerikDialog dialog = cut.FindComponent<TelerikDialog>().Instance;
// [Assert]
Assert.NotNull(dialog);
Assert.True(dialog.Title == "Close Form?");
}
} Then in the second razor test file (Form2Tests.razor): @inherits TestContext
@code {
public Form2Tests() {
Services.MockServices();
JSInterop.Mode = JSRuntimeMode.Loose;
RenderTree.Add<MainLayout>();
}
// Example Test method
public async void FormSubmission_ShouldPromptUserToConfirm() {
// [Arrange]
var cut = Render(
@<TelerikRootComponent>
<TelerikDialog />
<FormComponent2 />
</TelerikRootComponent>
);
FormService formService = Services.GetRequiredService<FormService>();
formService.Form.FirstField = "Test";
var formComponent2 = cut.FindComponent<FormComponent2>();
FieldIdentifier fieldIdentifier = formService.EditContext.Field(nameof(Form.FirstField));
await formComponent2.InvokeAsync(() => formService.EditContext.NotifyFieldChanged(fieldIdentifier));
// [Act]
cut.Find("button[name='cancel']").Click();
cut.WaitForState(() => cut.Find("div.k-dialog-title") != null);
TelerikDialog dialog = cut.FindComponent<TelerikDialog>().Instance;
// [Assert]
Assert.NotNull(dialog);
Assert.True(dialog.Title == "Close Form?");
}
} When each test file is run separately, the test pass as expected. But, when run together, I get something like [this is my actual Test Detail Summary]: ` Source: ClientFormComponentTests.razor line 108 Message: Stack Trace: Any ideas what I might be doing wrong here that could be causing this issue? I will also add that it specifically seems to fail when the dialog service OnChange subscribes to the components StateHasChanged event, if that makes anything more apparent. *Not sure why some of this didn't format correctly |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 12 replies
-
Hey, what isn’t directly apparent: Are you having some shared state between those tests? maybe also important: what testing framework are you using? So I would definitely make them async Task and check again |
Beta Was this translation helpful? Give feedback.
-
@egil and @linkdotnet "JustMock uses Castle Core to create proxies and the issue is caused by the attempt to emit the types at runtime with the same name. It seems to be specific to Bunit-style unit tests using razor files, and related to the types and namespaces mapping of the code blocks. Anyway, there is a relatively easy solution to the problem, you need just to modify the extension class as follows:" namespace DuplicateTypeNameRepro.Test.MockServices
{
public static class MockServices
{
static IWindowFactory windowFactory = Mock.Create<IWindowFactory>();
static IBrowserService browserService = Mock.Create<IBrowserService>();
static IMenuService menuService = Mock.Create<IMenuService>();
static IResizeListener resizeListener = Mock.Create<IResizeListener>();
static IJSRuntime jsRuntime = Mock.Create<IJSRuntime>();
static IContactInfoFormService contactInfoFormService = Mock.Create<IContactInfoFormService>();
static IDemographicInfoFormService demographicInfoFormService = Mock.Create<IDemographicInfoFormService>();
static IConfiguration configuration = Mock.Create<IConfiguration>();
public static void MockAppServices(this IServiceCollection services)
{
services.AddScoped<IDialogService, DialogService>();
services.AddScoped(provider => configuration);
services.AddScoped(provider => windowFactory);
services.AddScoped(provider => browserService);
services.AddScoped(provider => menuService);
services.AddScoped(provider => resizeListener);
services.AddScoped(provider => jsRuntime);
services.AddScoped(provider => contactInfoFormService);
services.AddScoped(provider => demographicInfoFormService);
}
}
} |
Beta Was this translation helpful? Give feedback.
@egil and @linkdotnet
The Telerik team figured out what was going on, I'll repeat what I received from them:
"JustMock uses Castle Core to create proxies and the issue is caused by the attempt to emit the types at runtime with the same name. It seems to be specific to Bunit-style unit tests using razor files, and related to the types and namespaces mapping of the code blocks. Anyway, there is a relatively easy solution to the problem, you need just to modify the extension class as follows:"