【问题标题】:Unable to load Type from Universal Assembly in Unit Test无法在单元测试中从通用程序集加载类型
【发布时间】:2014-06-29 06:40:21
【问题描述】:

我有一系列在项目中使用的通用可移植类库。 PCL 的所有目标都是 .NET 4.5、Windows 8、Windows phone 8、iOS 和 Android。该应用程序分为几个共享项目、存储库项目和服务项目。

然后我在解决方案中添加了一个标准单元测试项目。该项目针对所需的共享库以及我要测试的一个存储库库。当我运行测试时,我收到 System.TypeLoadException: Could not load Type 'BasicTaskRepository' from assembly.

我有几个具有相同目标的通用 PCL 程序集。我可以为任何其他程序集编写单元测试,它们可以工作并通过。出于某种原因,当我针对 Duty.Repositories.Tasks 程序集进行单元测试时,我得到了异常。

我的存储库接口和实现。

namespace Duty.Repositories.Shared
{
    public interface ITaskRepository
    {
        Task<IEnumerable<BasicTask>> GetTasks();
        Task<BasicTask> GetTask(Guid taskId);
        Task<BasicTask> SaveTask(BasicTask task);
        Task DeleteTask(BasicTask task);
        Task DeleteTask(Guid taskId);
    }
}

namespace Duty.Repositories.Tasks
{
    public class BasicTaskRepository : ITaskRepository
    {
        private ITaskService service;

        public BasicTaskRepository(ITaskService service)
        {
            this.service = service;
        }

        public async Task<IEnumerable<BasicTask>> GetTasks()
        {
            IEnumerable<BasicTask> tasks = await this.service.GetTasks();

            return tasks;
        }

        public async Task<BasicTask> GetTask(Guid taskId)
        {
            BasicTask task = await this.service.GetTask(taskId);
            return task;
        }
    }
}

接下来是我的 ITaskService 接口和实现。

namespace Duty.Services.Shared
{
    public interface ITaskService
    {
        Task<IEnumerable<BasicTask>> GetTasks();
        Task<BasicTask> GetTask(Guid taskId);
        Task<BasicTask> SaveTask(BasicTask task);
        Task DeleteTask(BasicTask task);
        Task DeleteTask(Guid taskId);
    }
}

namespace Duty.Services.ParseCloud
{
    public class TaskService : ITaskService
    {
        public TaskService()
        {
            ParseClient.Initialize("SomeKey", "AnotherKey");
        }

        public async Task<IEnumerable<BasicTask>> GetTasks()
        {
            ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name);
            IEnumerable<ParseObject> parseObjects = await query.FindAsync();

            // Convert the parse objects returned from the cloud into our local model representation.
            // We do this in order order to maintain support for the model across multiple cloud services
            // instead of restricting ourselves to the entire app using ParseCloud only.
            return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po));
        }

        public async Task<BasicTask> GetTask(Guid taskId)
        {
            ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name)
                .WhereEqualTo("ObjectId", taskId.ToString());
            IEnumerable<ParseObject> parseObjects = await query.FindAsync();

            return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po)).FirstOrDefault();
        }

        private BasicTask ConvertParseObjectToDutyTask(ParseObject parseObject)
        {
            Guid taskId = Guid.Empty;
            Guid.TryParse(parseObject.ObjectId, out taskId);

            return new BasicTask
            {
                TaskId = taskId,
                Title = parseObject["Title"].ToString(),
                IsCompleted = (bool)parseObject["IsCompleted"],
            };
        }
    }
}

最后,我的两个单元测试。访问存储库的单元测试失败并出现上述异常,而直接访问服务的单元测试每次都通过。

public class BasicTaskRepositoryTests
{
    private ITaskService taskService;

    [TestInitialize]
    public void Setup()
    {
        var basicTasks = new List<BasicTask>()
        {
            new BasicTask { Title = "Test Title 1", TaskId = Guid.Empty },
            new BasicTask { Title = "Test Title 2", TaskId = Guid.Empty, },
        };

        var serviceMock = new Mock<ITaskService>();

        // Set up our mock service object.
        serviceMock.Setup(service => service.GetTasks()).ReturnsAsync(basicTasks);
        serviceMock.Setup(service => service.GetTask(It.IsAny<Guid>()))
            .ReturnsAsync(basicTasks.FirstOrDefault());
        serviceMock.Setup(service => service.SaveTask(It.IsAny<BasicTask>()))
            .ReturnsAsync(basicTasks.FirstOrDefault());
        serviceMock.Setup(service => service.DeleteTask(It.IsAny<BasicTask>()))
            .Returns<BasicTask>(null);

        this.taskService = serviceMock.Object;
    }

    [TestMethod]
    public async Task TaskRepository_GetBasicTasks_HasTasks()
    {
        // Arrange
        var taskRepository = new Duty.Repositories.Tasks.BasicTaskRepository(taskService);

        // Act
        IEnumerable<BasicTask> tasks = await taskRepository.GetTasks();

        // Assert
        Assert.AreEqual<int>(2, tasks.Count());
    }

    [TestMethod]
    public async Task TaskService_GetBasicTasks_HasTasks()
    {
        // Arrange
        var serviceRepo = new Services.ParseCloud.TaskService();

        // Act
        IEnumerable<BasicTask> tasks = await serviceRepo.GetTasks();

        // Assert
        Assert.AreEqual(2, tasks.Count());
    }
}

同样,我所有的库都是面向 .NET 4.5、Windows 8、Windows Phone 8.1、iOS 和 Android 的 PCL。服务 PCL 和存储库 PCL 之间没有目标差异。单元测试项目是标准单元测试(非 Windows 通用),但我很难发现这是问题所在,因为服务测试引用通用 PCL 没有问题。

我已经从解决方案中删除了 Repositories 项目,重新构建并重新运行了测试(如建议的in similar post here),然后重新添加了项目;这并没有解决问题。

我删除了整个项目并重新创建了它,但仍然是同样的问题。我删除了对 Moq 的引用并将 Service 直接传递到 Repository 构造函数,结果完全相同。它找不到程序集。

这是我尝试从等式中删除 Moq。

    public void Setup()
    {
        var basicTasks = new List<BasicTask>()
        {
            new BasicTask { Title = "Test Title 1", TaskId = Guid.Empty },
            new BasicTask { Title = "Test Title 2", TaskId = Guid.Empty, },
        };
    }

    [TestMethod]
    public async Task TaskRepository_GetBasicTasks_HasTasks()
    {
        // Arrange
        var taskRepository = new Duty.Repositories.Tasks.BasicTaskRepository(
            new Duty.Services.ParseCloud.TaskService());

        // Act
        IEnumerable<BasicTask> tasks = await taskRepository.GetTasks();

        // Assert
        Assert.AreEqual<int>(2, tasks.Count());
    }

任何人都可以提供任何帮助吗?我完全不知所措。

Test Name:  TaskRepository_GetBasicTasks_HasTasks
Test FullName:  Duty.UnitTests.Repositories.Tasks.BasicTaskRepositoryTests.TaskRepository_GetBasicTasks_HasTasks
Test Source:    c:\Source\Workspaces\sullinger.visualstudio.com\Duty\Main\App\DutyApp\Duty.UnitTests\Duty.Repositories\Duty.Repositories.Tasks\BasicTaskRepositoryTests.cs : line 42
Test Outcome:   Failed
Test Duration:  0:00:00.0295863

Result Message: 
Test method Duty.UnitTests.Repositories.Tasks.BasicTaskRepositoryTests.TaskRepository_GetBasicTasks_HasTasks threw exception: 
System.TypeLoadException: Could not load type 'Duty.Repositories.Tasks.BasicTaskRepository' from assembly 'Duty.Repositories.Tasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Result StackTrace:  
at Duty.UnitTests.Repositories.Tasks.BasicTaskRepositoryTests.<TaskRepository_GetBasicTasks_HasTasks>d__3.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at Duty.UnitTests.Repositories.Tasks.BasicTaskRepositoryTests.TaskRepository_GetBasicTasks_HasTasks()

提前致谢!

【问题讨论】:

  • 大胆猜测 - 您的测试项目是否针对正确的 .NET 框架?
  • 感谢乔治的回复,问题是我的单元测试和库错误地共享了相同的项目名称。

标签: c# unit-testing unity-container moq win-universal-app


【解决方案1】:

我能够解决这个问题。我的项目结构如下所示

Solution
  |___Repositories
  |_______Duty.Repositories.Tasks
  |___Tests
  |______Repositories
  |___________Duty.Repositories.Tasks

我的单元测试项目与我的存储库项目命名相同。一旦我将我的单元测试项目重命名为 Duty.Repositories.TasksTests (无论如何都应该如此),它就解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2011-09-07
    • 2016-09-27
    相关资源
    最近更新 更多